Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-02-02 Thread Zoltán Kővágó

On 2020-01-28 09:30, Volker Rümelin wrote:

Hi,

Unfortunately it's not that simple to simply revert the patch since the old 
backend api no longer exists.  Also I don't have a Mac so it's almost 
impossible for me to test the results.  I looked at the specified commit and I 
think I found a problem, could you please apply the attached patch on the 
current git master and check whether it solves the problem?  If yes I'll turn 
it into a proper patch.

Regards,
Zoltan



Hi Zoltán,

I also don't have a Mac so I tested your patch with a slightly modified 
sdlaudio version. I found two bugs in your patch. With the bugs fixed I have 
working SDL2 audio playback with float type samples. Now I wonder if the fixed 
patch also fixes coreaudio playback. Depending on how busy you are I can just 
write a review for your patch and let you handle the rest, or may I send a 
modified version of your patch to the mailing list for testing?

With best regards
Volker

Hi,

Maybe I'm a bit late since you already did it, but go ahead, I don't 
have too much time to work on qemu recently.


Regards,
Zoltan



Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-28 Thread Volker Rümelin


>
> Hi Volker,
>
> I can test for coreaudio. Can you let us know exactly what you fixed in the 
> patch?

Hi Howard,

I wrote a patch that tries to fix the problems in Zoltán's patch. The changes 
in coreaudio.c are untested. I'll send it as a reply to this mail. Please apply 
Zoltan's patch and then my patch to qemu master.

> While cross compiling for windows, I saw these errors (besides some casting 
> issues):
> line 56: buffer2  (should be *buffer2?)
> line 455: ret  (should be ret2?)
>
> audio/dsoundaudio.c:56:20: error: variable or field 'buffer2' declared void
>    56 |     void *buffer1, buffer2;
>       |                    ^~~
> audio/dsoundaudio.c: In function 'dsound_get_buffer_out':

I'm sorry, but I can't build and test on Windows.

With best regards,
Volker



Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-28 Thread Howard Spoelstra
On Tue, Jan 28, 2020 at 9:30 AM Volker Rümelin  wrote:

> > Hi,
> >
> > Unfortunately it's not that simple to simply revert the patch since the
> old backend api no longer exists.  Also I don't have a Mac so it's almost
> impossible for me to test the results.  I looked at the specified commit
> and I think I found a problem, could you please apply the attached patch on
> the current git master and check whether it solves the problem?  If yes
> I'll turn it into a proper patch.
> >
> > Regards,
> > Zoltan
> >
>
> Hi Zoltán,
>
> I also don't have a Mac so I tested your patch with a slightly modified
> sdlaudio version. I found two bugs in your patch. With the bugs fixed I
> have working SDL2 audio playback with float type samples. Now I wonder if
> the fixed patch also fixes coreaudio playback. Depending on how busy you
> are I can just write a review for your patch and let you handle the rest,
> or may I send a modified version of your patch to the mailing list for
> testing?
>
> With best regards
> Volker
>

Hi Volker,

I can test for coreaudio. Can you let us know exactly what you fixed in the
patch?
While cross compiling for windows, I saw these errors (besides some casting
issues):
line 56: buffer2  (should be *buffer2?)
line 455: ret  (should be ret2?)

audio/dsoundaudio.c:56:20: error: variable or field 'buffer2' declared void
   56 | void *buffer1, buffer2;
  |^~~
audio/dsoundaudio.c: In function 'dsound_get_buffer_out':
audio/dsoundaudio.c:428:18: error: returning 'int' from a function with
return type 'void *' makes pointer from integer without a cast
[-Werror=int-conversion]
  428 | return ds->buffer2;
  |~~^
audio/dsoundaudio.c:451:17: error: assignment to 'int' from 'void *' makes
integer from pointer without a cast [-Werror=int-conversion]
  451 | ds->buffer2 = ret2;
  | ^
audio/dsoundaudio.c:455:12: error: 'ret' undeclared (first use in this
function); did you mean 'ret2'?
  455 | return ret;
  |^~~
  |ret2
audio/dsoundaudio.c:455:12: note: each undeclared identifier is reported
only once for each function it appears in
audio/dsoundaudio.c: In function 'dsound_put_buffer_out':
audio/dsoundaudio.c:471:49: error: passing argument 3 of
'dsound_unlock_out' makes pointer from integer without a cast
[-Werror=int-conversion]
  471 | err = dsound_unlock_out(dsb, ds->buffer1, ds->buffer2,
ds->size1, ds->size2);
  |   ~~^
  | |
  | int
In file included from audio/dsoundaudio.c:267:
audio/dsound_template.h:49:12: note: expected 'LPVOID' {aka 'void *'} but
argument is of type 'int'
   49 | LPVOID p2,
  | ~~~^~
audio/dsoundaudio.c: In function 'dsound_get_buffer_out':
audio/dsoundaudio.c:456:1: error: control reaches end of non-void function
[-Werror=return-type]
  456 | }
  | ^
cc1: all warnings being treated as errors

Best,
Howard


Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-28 Thread Volker Rümelin
> Hi,
>
> Unfortunately it's not that simple to simply revert the patch since the old 
> backend api no longer exists.  Also I don't have a Mac so it's almost 
> impossible for me to test the results.  I looked at the specified commit and 
> I think I found a problem, could you please apply the attached patch on the 
> current git master and check whether it solves the problem?  If yes I'll turn 
> it into a proper patch.
>
> Regards,
> Zoltan
>

Hi Zoltán,

I also don't have a Mac so I tested your patch with a slightly modified 
sdlaudio version. I found two bugs in your patch. With the bugs fixed I have 
working SDL2 audio playback with float type samples. Now I wonder if the fixed 
patch also fixes coreaudio playback. Depending on how busy you are I can just 
write a review for your patch and let you handle the rest, or may I send a 
modified version of your patch to the mailing list for testing?

With best regards
Volker



Ping: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-12 Thread John Arbuckle
Ping

https://patchwork.kernel.org/patch/11311763/

This patch enables the playback of audio on a Mac OS 9 or Mac OS X guest.

Signed-off-by: John Arbuckle 
---
v2 changes:
- Fixed a bug that prevented the sampling rate from being changed.

 hw/audio/Kconfig  |   3 +
 hw/audio/Makefile.objs|   2 +
 hw/audio/screamer.c   | 993 ++
 hw/misc/macio/macio.c |  35 +-
 hw/ppc/Kconfig|   1 +
 hw/ppc/mac.h  |   5 +
 include/hw/audio/screamer.h   |  42 ++
 include/hw/misc/macio/macio.h |   2 +
 8 files changed, 1082 insertions(+), 1 deletion(-)
 create mode 100644 hw/audio/screamer.c
 create mode 100644 include/hw/audio/screamer.h

diff --git a/hw/audio/Kconfig b/hw/audio/Kconfig
index e9c6fed826..196da6c3fe 100644
--- a/hw/audio/Kconfig
+++ b/hw/audio/Kconfig
@@ -50,3 +50,6 @@ config CS4231
 
 config MARVELL_88W8618
 bool
+
+config SCREAMER
+bool
diff --git a/hw/audio/Makefile.objs b/hw/audio/Makefile.objs
index 63db383709..55906886bc 100644
--- a/hw/audio/Makefile.objs
+++ b/hw/audio/Makefile.objs
@@ -15,4 +15,6 @@ common-obj-$(CONFIG_CS4231) += cs4231.o
 common-obj-$(CONFIG_MARVELL_88W8618) += marvell_88w8618.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-ac97.o
 
+common-obj-$(CONFIG_SCREAMER) += screamer.o
+
 common-obj-y += soundhw.o
diff --git a/hw/audio/screamer.c b/hw/audio/screamer.c
new file mode 100644
index 00..d3a86d2e67
--- /dev/null
+++ b/hw/audio/screamer.c
@@ -0,0 +1,993 @@
+/*
+ * File: Screamer.c
+ * Description: Implement the Screamer sound chip used in Apple Macintoshes.
+ * It works by filling a buffer, then playing the buffer.
+ */
+
+#include "qemu/osdep.h"
+#include "audio/audio.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include 
+#include "hw/ppc/mac.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "include/hw/audio/screamer.h"
+
+#define DEBUG_SCREAMER 0
+#define DPRINTF(fmt, ...) \
+do { if (DEBUG_SCREAMER) { printf(fmt , ## __VA_ARGS__); } } while (0)
+
+#define SOUND_CONTROL_REG  0
+#define CODEC_CONTROL_REG  1
+#define CODEC_STATUS_REG   2
+#define CLIP_COUNT_REG 3
+#define BYTE_SWAP_REG  4
+#define FRAME_COUNT_REG5
+
+#define AWACS_BUSY 0x0100
+
+/* Used with AWACS register 1 */
+#define RECALIBRATE 0x004
+#define LOOPTHRU0x040
+#define SPEAKER_MUTE0x080
+#define HEADPHONE_MUTE  0x200
+#define OUTPUT_ZERO 0x400
+#define OUTPUT_ONE  0x800
+#define PARALLEL_OUTPUT 0xc00
+
+/* Function prototypes */
+static uint32_t set_busy_bit(uint32_t value, int bit);
+static uint32_t set_part_ready_bit(uint32_t value, int bit_value);
+static uint32_t set_revision(uint32_t input_value);
+static uint32_t set_manufacturer(uint32_t input_value);
+static int get_sampling_rate(ScreamerState *s);
+static uint32_t get_frame_count_reg(ScreamerState *s);
+static void add_to_speaker_buffer(DBDMA_io *io);
+static void dma_request(DBDMA_io *io);
+
+
+/ Getters */
+
+/* Returns the codec control register's encoded AWACS address */
+static uint8_t get_codec_control_address(uint32_t value)
+{
+uint8_t return_value;
+return_value = (value >> 12) & 0x0fff;
+return return_value;
+}
+
+
+static uint32_t get_sound_control_reg(ScreamerState *s)
+{
+DPRINTF("%s() called - returned 0x%x\n", __func__, s->sound_control);
+return s->sound_control;
+}
+
+/* The AWACS registers are accessed thru this register */
+static uint32_t get_codec_control_reg(ScreamerState *s)
+{
+int awacs_register = get_codec_control_address(s->codec_control);
+uint32_t return_value = s->awacs[awacs_register];
+return_value = set_busy_bit(return_value, 0); /* Tell CPU we are ready */
+DPRINTF("%s() called - returned 0x%x\tAWACS register: %d\n", __func__,
+return_value, awacs_register);
+return return_value;
+}
+
+/*
+ * Determines if the readback bit is set.
+ * It is used by the Codec Control register.
+ */
+static bool readback_enabled(ScreamerState *s)
+{
+/* Note: bit zero is the readback enabled bit */
+if (s->awacs[7] & 1) {
+return true;
+} else {
+return false;
+}
+}
+
+static uint32_t get_codec_status_reg(ScreamerState *s)
+{
+uint32_t return_value;
+
+/* if in readback mode - return AWACS register value */
+if (readback_enabled(s)) {
+int awacs_register = (s->awacs[7] & 0xe) >> 1;
+s->awacs[7] = s->awacs[7] & 0xfffe; /* turn off readback mode */
+return_value = s->awacs[awacs_register] << 4;
+DPRINTF("readback enable bit is set, returning AWACS register %d\t"
+"value:0x%x\n", awacs_register, return_value);
+
+return return_value;
+}
+
+/* Tell CPU we are ready */
+return_value = set_part_ready_bit(s->codec_status, 1);
+
+/* Set Revision to Screamer */
+return_value = 

Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-10 Thread Programmingkid


> On Jan 10, 2020, at 7:32 PM, Zoltán Kővágó  wrote:
> 
> On 2020-01-05 02:58, Programmingkid wrote:
>> I found the patch that breaks Screamer sound support for qemu-system-ppc. It 
>> is this:
>> commit 2ceb8240fa4e4e30fb853565eb2bed3032d74f62
>> Author: Kővágó, Zoltán 
>> Date:   Thu Sep 19 23:24:11 2019 +0200
>> coreaudio: port to the new audio backend api
>>  Signed-off-by: Kővágó, Zoltán 
>> Message-id: 
>> 586a1e66de5cbc6c5234f9ae556d24befb6afada.1568927990.git.dirty.ice...@gmail.com
>> Signed-off-by: Gerd Hoffmann 
>> Reversing this patch should make the Screamer patch work with the current 
>> git version of QEMU.
> 
> Hi,
> 
> Unfortunately it's not that simple to simply revert the patch since the old 
> backend api no longer exists.  Also I don't have a Mac so it's almost 
> impossible for me to test the results.  I looked at the specified commit and 
> I think I found a problem, could you please apply the attached patch on the 
> current git master and check whether it solves the problem?  If yes I'll turn 
> it into a proper patch.
> 
> Regards,
> Zoltan
> 
> 

Sorry it did not fix the problem. I only hear pops occasionally. Most of the 
time only silence can be heard.

Thank you for the patch. 


Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-10 Thread Zoltán Kővágó

On 2020-01-05 02:58, Programmingkid wrote:

I found the patch that breaks Screamer sound support for qemu-system-ppc. It is 
this:

commit 2ceb8240fa4e4e30fb853565eb2bed3032d74f62
Author: Kővágó, Zoltán 
Date:   Thu Sep 19 23:24:11 2019 +0200

 coreaudio: port to the new audio backend api
 
 Signed-off-by: Kővágó, Zoltán 

 Message-id: 
586a1e66de5cbc6c5234f9ae556d24befb6afada.1568927990.git.dirty.ice...@gmail.com
 Signed-off-by: Gerd Hoffmann 


Reversing this patch should make the Screamer patch work with the current git 
version of QEMU.



Hi,

Unfortunately it's not that simple to simply revert the patch since the 
old backend api no longer exists.  Also I don't have a Mac so it's 
almost impossible for me to test the results.  I looked at the specified 
commit and I think I found a problem, could you please apply the 
attached patch on the current git master and check whether it solves the 
problem?  If yes I'll turn it into a proper patch.


Regards,
Zoltan

diff --git a/audio/audio_template.h b/audio/audio_template.h
index 3287d7075e..a7b46b8363 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -153,6 +153,13 @@ static int glue (audio_pcm_sw_init_, TYPE) (
 sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
 #endif
 
+#ifdef FLOAT_MIXENG
+#ifdef DAC
+sw->conv = mixeng_conv_float;
+#else
+sw->clip = mixeng_clip_float;
+#endif
+#else
 #ifdef DAC
 sw->conv = mixeng_conv
 #else
@@ -162,6 +169,7 @@ static int glue (audio_pcm_sw_init_, TYPE) (
 [sw->info.sign]
 [sw->info.swap_endianness]
 [audio_bits_to_index (sw->info.bits)];
+#endif
 
 sw->name = g_strdup (name);
 err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
diff --git a/audio/mixeng.h b/audio/mixeng.h
index 18e62c7c49..343f5fb810 100644
--- a/audio/mixeng.h
+++ b/audio/mixeng.h
@@ -41,6 +41,11 @@ typedef void (f_sample) (void *dst, const struct st_sample *src, int samples);
 extern t_sample *mixeng_conv[2][2][2][3];
 extern f_sample *mixeng_clip[2][2][2][3];
 
+#ifdef FLOAT_MIXENG
+void mixeng_conv_float(struct st_sample *dst, const void *src, int samples);
+void mixeng_clip_float(void *dst, const struct st_sample *src, int samples);
+#endif
+
 void *st_rate_start (int inrate, int outrate);
 void st_rate_flow(void *opaque, st_sample *ibuf, st_sample *obuf,
   size_t *isamp, size_t *osamp);
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 66f0f459cf..4e7e509ad0 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -471,20 +471,6 @@ static OSStatus audioDeviceIOProc(
 return 0;
 }
 
-static UInt32 coreaudio_get_flags(struct audio_pcm_info *info,
-  struct audsettings *as)
-{
-UInt32 flags = info->sign ? kAudioFormatFlagIsSignedInteger : 0;
-if (as->endianness) { /* 0 = little, 1 = big */
-flags |= kAudioFormatFlagIsBigEndian;
-}
-
-if (flags == 0) { /* must not be 0 */
-flags = kAudioFormatFlagsAreAllClear;
-}
-return flags;
-}
-
 static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
   void *drv_opaque)
 {
@@ -572,15 +558,6 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
 
 /* set Samplerate */
 core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
-core->outputStreamBasicDescription.mFormatID = kAudioFormatLinearPCM;
-core->outputStreamBasicDescription.mFormatFlags =
-coreaudio_get_flags(>info, as);
-core->outputStreamBasicDescription.mBytesPerPacket =
-core->outputStreamBasicDescription.mBytesPerFrame =
-hw->info.nchannels * hw->info.bits / 8;
-core->outputStreamBasicDescription.mFramesPerPacket = 1;
-core->outputStreamBasicDescription.mChannelsPerFrame = hw->info.nchannels;
-core->outputStreamBasicDescription.mBitsPerChannel = hw->info.bits;
 
 status = coreaudio_set_streamformat(core->outputDeviceID,
 >outputStreamBasicDescription);
diff --git a/audio/mixeng.c b/audio/mixeng.c
index 2f5ba71381..424ffe30d7 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -267,6 +267,27 @@ f_sample *mixeng_clip[2][2][2][3] = {
 }
 };
 
+#ifdef FLOAT_MIXENG
+void mixeng_conv_float(struct st_sample *dst, const void *src, int samples)
+{
+float *in = (float *) src;
+while (samples--) {
+dst->l = *in++;
+dst->r = *in++;
+dst++;
+}
+}
+
+void mixeng_clip_float(void *dst, const struct st_sample *src, int samples)
+{
+float *out = (float *) dst;
+while (samples--) {
+*out++ = src->l;
+*out++ = src->r;
+src++;
+}
+}
+#endif
 
 void audio_sample_to_uint64(void *samples, int pos,
 uint64_t *left, uint64_t *right)


Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-05 Thread Programmingkid


> On Jan 4, 2020, at 8:58 PM, Programmingkid  wrote:
> 
> I found the patch that breaks Screamer sound support for qemu-system-ppc. It 
> is this:
> 
> commit 2ceb8240fa4e4e30fb853565eb2bed3032d74f62
> Author: Kővágó, Zoltán 
> Date:   Thu Sep 19 23:24:11 2019 +0200
> 
>coreaudio: port to the new audio backend api
> 
>Signed-off-by: Kővágó, Zoltán 
>Message-id: 
> 586a1e66de5cbc6c5234f9ae556d24befb6afada.1568927990.git.dirty.ice...@gmail.com
>Signed-off-by: Gerd Hoffmann 
> 
> 
> Reversing this patch should make the Screamer patch work with the current git 
> version of QEMU.

@Peter Maydell

Does QEMU play audio correctly on your version of Mac OS X? I am using Mac OS 
10.12 and the audio sound demonically loud and scary. I am currently at this 
git revision:

f0dcfddecee8b860e015bb07d67cfcbdfbfd51d

Merge: 40f09ee833 725fe5d10d
Author: Peter Maydell 
Date:   Fri Jan 3 17:18:08 2020 +

Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' 
into staging

I have ran several tests with qemu-system-i386 using Windows guest with the 
ac97 and sb16 sound cards. It sounds just as bad for me on qemu-system-ppc. 

Thank you.


Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-04 Thread Programmingkid
I found the patch that breaks Screamer sound support for qemu-system-ppc. It is 
this:

commit 2ceb8240fa4e4e30fb853565eb2bed3032d74f62
Author: Kővágó, Zoltán 
Date:   Thu Sep 19 23:24:11 2019 +0200

coreaudio: port to the new audio backend api

Signed-off-by: Kővágó, Zoltán 
Message-id: 
586a1e66de5cbc6c5234f9ae556d24befb6afada.1568927990.git.dirty.ice...@gmail.com
Signed-off-by: Gerd Hoffmann 


Reversing this patch should make the Screamer patch work with the current git 
version of QEMU.


[PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2019-12-28 Thread John Arbuckle
This patch enables the playback of audio on a Mac OS 9 or Mac OS X guest.

Signed-off-by: John Arbuckle 
---
v2 changes:
- Fixed a bug that prevented the sampling rate from being changed.

 hw/audio/Kconfig  |   3 +
 hw/audio/Makefile.objs|   2 +
 hw/audio/screamer.c   | 993 ++
 hw/misc/macio/macio.c |  35 +-
 hw/ppc/Kconfig|   1 +
 hw/ppc/mac.h  |   5 +
 include/hw/audio/screamer.h   |  42 ++
 include/hw/misc/macio/macio.h |   2 +
 8 files changed, 1082 insertions(+), 1 deletion(-)
 create mode 100644 hw/audio/screamer.c
 create mode 100644 include/hw/audio/screamer.h

diff --git a/hw/audio/Kconfig b/hw/audio/Kconfig
index e9c6fed826..196da6c3fe 100644
--- a/hw/audio/Kconfig
+++ b/hw/audio/Kconfig
@@ -50,3 +50,6 @@ config CS4231
 
 config MARVELL_88W8618
 bool
+
+config SCREAMER
+bool
diff --git a/hw/audio/Makefile.objs b/hw/audio/Makefile.objs
index 63db383709..55906886bc 100644
--- a/hw/audio/Makefile.objs
+++ b/hw/audio/Makefile.objs
@@ -15,4 +15,6 @@ common-obj-$(CONFIG_CS4231) += cs4231.o
 common-obj-$(CONFIG_MARVELL_88W8618) += marvell_88w8618.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-ac97.o
 
+common-obj-$(CONFIG_SCREAMER) += screamer.o
+
 common-obj-y += soundhw.o
diff --git a/hw/audio/screamer.c b/hw/audio/screamer.c
new file mode 100644
index 00..d3a86d2e67
--- /dev/null
+++ b/hw/audio/screamer.c
@@ -0,0 +1,993 @@
+/*
+ * File: Screamer.c
+ * Description: Implement the Screamer sound chip used in Apple Macintoshes.
+ * It works by filling a buffer, then playing the buffer.
+ */
+
+#include "qemu/osdep.h"
+#include "audio/audio.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include 
+#include "hw/ppc/mac.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "include/hw/audio/screamer.h"
+
+#define DEBUG_SCREAMER 0
+#define DPRINTF(fmt, ...) \
+do { if (DEBUG_SCREAMER) { printf(fmt , ## __VA_ARGS__); } } while (0)
+
+#define SOUND_CONTROL_REG  0
+#define CODEC_CONTROL_REG  1
+#define CODEC_STATUS_REG   2
+#define CLIP_COUNT_REG 3
+#define BYTE_SWAP_REG  4
+#define FRAME_COUNT_REG5
+
+#define AWACS_BUSY 0x0100
+
+/* Used with AWACS register 1 */
+#define RECALIBRATE 0x004
+#define LOOPTHRU0x040
+#define SPEAKER_MUTE0x080
+#define HEADPHONE_MUTE  0x200
+#define OUTPUT_ZERO 0x400
+#define OUTPUT_ONE  0x800
+#define PARALLEL_OUTPUT 0xc00
+
+/* Function prototypes */
+static uint32_t set_busy_bit(uint32_t value, int bit);
+static uint32_t set_part_ready_bit(uint32_t value, int bit_value);
+static uint32_t set_revision(uint32_t input_value);
+static uint32_t set_manufacturer(uint32_t input_value);
+static int get_sampling_rate(ScreamerState *s);
+static uint32_t get_frame_count_reg(ScreamerState *s);
+static void add_to_speaker_buffer(DBDMA_io *io);
+static void dma_request(DBDMA_io *io);
+
+
+/ Getters */
+
+/* Returns the codec control register's encoded AWACS address */
+static uint8_t get_codec_control_address(uint32_t value)
+{
+uint8_t return_value;
+return_value = (value >> 12) & 0x0fff;
+return return_value;
+}
+
+
+static uint32_t get_sound_control_reg(ScreamerState *s)
+{
+DPRINTF("%s() called - returned 0x%x\n", __func__, s->sound_control);
+return s->sound_control;
+}
+
+/* The AWACS registers are accessed thru this register */
+static uint32_t get_codec_control_reg(ScreamerState *s)
+{
+int awacs_register = get_codec_control_address(s->codec_control);
+uint32_t return_value = s->awacs[awacs_register];
+return_value = set_busy_bit(return_value, 0); /* Tell CPU we are ready */
+DPRINTF("%s() called - returned 0x%x\tAWACS register: %d\n", __func__,
+return_value, awacs_register);
+return return_value;
+}
+
+/*
+ * Determines if the readback bit is set.
+ * It is used by the Codec Control register.
+ */
+static bool readback_enabled(ScreamerState *s)
+{
+/* Note: bit zero is the readback enabled bit */
+if (s->awacs[7] & 1) {
+return true;
+} else {
+return false;
+}
+}
+
+static uint32_t get_codec_status_reg(ScreamerState *s)
+{
+uint32_t return_value;
+
+/* if in readback mode - return AWACS register value */
+if (readback_enabled(s)) {
+int awacs_register = (s->awacs[7] & 0xe) >> 1;
+s->awacs[7] = s->awacs[7] & 0xfffe; /* turn off readback mode */
+return_value = s->awacs[awacs_register] << 4;
+DPRINTF("readback enable bit is set, returning AWACS register %d\t"
+"value:0x%x\n", awacs_register, return_value);
+
+return return_value;
+}
+
+/* Tell CPU we are ready */
+return_value = set_part_ready_bit(s->codec_status, 1);
+
+/* Set Revision to Screamer */
+return_value = set_revision(return_value);
+
+/* Set the Manufacturer to Crystal */
+