aica: Update to the latest version
authorJason Self <j@jxself.org>
Sat, 16 Jan 2021 17:12:41 +0000 (09:12 -0800)
committerJason Self <j@jxself.org>
Sat, 16 Jan 2021 17:12:41 +0000 (09:12 -0800)
WHENCE
aica/arm/aica.c
aica/arm/aica_cmd_iface.h
aica/arm/aica_comm.h [new file with mode: 0644]

diff --git a/WHENCE b/WHENCE
index 756de43b4b48d0fc3fe983e377ba2338f5ebcf6a..698ea321d8e74529aca97605f997c91855304850 100644 (file)
--- a/WHENCE
+++ b/WHENCE
@@ -48,8 +48,8 @@ From http://www.zdomain.com/a56.html
 
 aica: Firmware for the sound card in the Sega Dreamcast
 
-Version: Based on commit 832ea65b43c8b402f19f3b6b3ecb8804f73c948a
-dated 17 May 2018
+Version: Based on commit fae2358ca346842f3f4d36237be3994fe6135139
+dated 7 October 2020
 
 License: KOS License (see README.KOS)
 
index 2ff2ca1058058efe3f35d4ed9936d00b7deaa8d3..411922bbd4469a0c08b19558e69786e01aa98d90 100644 (file)
@@ -96,7 +96,6 @@ void aica_play(int ch, int delay) {
 
     uint32 freq_lo, freq_base = 5644800;
     int freq_hi = 7;
-    uint32 i;
     uint32 playCont;
 
     /* Stop the channel (if it's already playing) */
@@ -124,14 +123,13 @@ void aica_play(int ch, int delay) {
     /* Write resulting values */
     CHNREG32(ch, 24) = (freq_hi << 11) | (freq_lo & 1023);
 
-    /* Set volume, pan */
+    /* Convert the incoming pan into a hardware value and set it */
     CHNREG8(ch, 36) = calc_aica_pan(pan);
     CHNREG8(ch, 37) = 0xf;
     /* turn off Low Pass Filter (LPF) */
     CHNREG8(ch, 40) = 0x24;
-    /* Convert the incoming volume and pan into hardware values */
-    /* Vol starts at zero so we can ramp */
-    CHNREG8(ch, 41) = 0xff;
+    /* Convert the incoming volume into a hardware value and set it */
+    CHNREG8(ch, 41) = calc_aica_vol(vol);
 
     /* If we supported volume envelopes (which we don't yet) then
        this value would set that up. The top 4 bits determine the
@@ -149,21 +147,15 @@ void aica_play(int ch, int delay) {
        also set the bits to start playback here. */
     CHNREG32(ch, 4) = smpptr & 0xffff;
     playCont = (mode << 7) | (smpptr >> 16);
-    vol = calc_aica_vol(vol);
 
     if(loopflag)
         playCont |= 0x0200;
 
     if(delay) {
         CHNREG32(ch, 0) = playCont;         /* key off */
-        CHNREG8(ch, 41) = vol;
     }
     else {
         CHNREG32(ch, 0) = 0xc000 | playCont;    /* key on */
-
-        /* ramp up the volume */
-        for(i = 0xff; i >= vol; i--)
-            CHNREG8(ch, 41) = i;
     }
 }
 
index aba0a51942f04dbb83735013ab535b502cb9dde8..0c88580a2cccdf1438116b3094573996f4613dca 100644 (file)
 #ifndef __ARM_AICA_CMD_IFACE_H
 #define __ARM_AICA_CMD_IFACE_H
 
-#ifndef __ARCH_TYPES_H
-typedef unsigned long uint8;
-typedef unsigned long uint32;
-#endif
-
-/* Command queue; one of these for passing data from the SH-4 to the
-   AICA, and another for the other direction. If a command is written
-   to the queue and it is longer than the amount of space between the
-   head point and the queue size, the command will wrap around to
-   the beginning (i.e., queue commands _can_ be split up). */
-typedef struct aica_queue {
-    uint32      head;       /* Insertion point offset (in bytes) */
-    uint32      tail;       /* Removal point offset (in bytes) */
-    uint32      size;       /* Queue size (in bytes) */
-    uint32      valid;      /* 1 if the queue structs are valid */
-    uint32      process_ok; /* 1 if it's ok to process the data */
-    uint32      data;       /* Pointer to queue data buffer */
-} aica_queue_t;
-
-/* Command queue struct for commanding the AICA from the SH-4 */
-typedef struct aica_cmd {
-    uint32      size;       /* Command data size in dwords */
-    uint32      cmd;        /* Command ID */
-    uint32      timestamp;  /* When to execute the command (0 == now) */
-    uint32      cmd_id;     /* Command ID, for cmd/response pairs, or channel id */
-    uint32      misc[4];    /* Misc Parameters / Padding */
-    uint8       cmd_data[]; /* Command data */
-} aica_cmd_t;
-
-/* Maximum command size -- 256 dwords */
-#define AICA_CMD_MAX_SIZE   256
-
-/* This is the cmd_data for AICA_CMD_CHAN. Make this 16 dwords long
-   for two aica bus queues. */
-typedef struct aica_channel {
-    uint32      cmd;        /* Command ID */
-    uint32      base;       /* Sample base in RAM */
-    uint32      type;       /* (8/16bit/ADPCM) */
-    uint32      length;     /* Sample length */
-    uint32      loop;       /* Sample looping */
-    uint32      loopstart;  /* Sample loop start */
-    uint32      loopend;    /* Sample loop end */
-    uint32      freq;       /* Frequency */
-    uint32      vol;        /* Volume 0-255 */
-    uint32      pan;        /* Pan 0-255 */
-    uint32      pos;        /* Sample playback pos */
-    uint32      pad[5];     /* Padding */
-} aica_channel_t;
-
-/* Declare an aica_cmd_t big enough to hold an aica_channel_t
-   using temp name T, aica_cmd_t name CMDR, and aica_channel_t name CHANR */
-#define AICA_CMDSTR_CHANNEL(T, CMDR, CHANR) \
-    uint8   T[sizeof(aica_cmd_t) + sizeof(aica_channel_t)]; \
-    aica_cmd_t  * CMDR = (aica_cmd_t *)T; \
-    aica_channel_t  * CHANR = (aica_channel_t *)(CMDR->cmd_data);
-#define AICA_CMDSTR_CHANNEL_SIZE    ((sizeof(aica_cmd_t) + sizeof(aica_channel_t))/4)
-
-/* Command values (for aica_cmd_t) */
-#define AICA_CMD_NONE       0x00000000  /* No command (dummy packet)    */
-#define AICA_CMD_PING       0x00000001  /* Check for signs of life  */
-#define AICA_CMD_CHAN       0x00000002  /* Perform a wavetable action   */
-#define AICA_CMD_SYNC_CLOCK 0x00000003  /* Reset the millisecond clock  */
-
-/* Response values (for aica_cmd_t) */
-#define AICA_RESP_NONE      0x00000000
-#define AICA_RESP_PONG      0x00000001  /* Response to CMD_PING             */
-#define AICA_RESP_DBGPRINT  0x00000002  /* Entire payload is a null-terminated string   */
-
-/* Command values (for aica_channel_t commands) */
-#define AICA_CH_CMD_MASK    0x0000000f
-
-#define AICA_CH_CMD_NONE    0x00000000
-#define AICA_CH_CMD_START   0x00000001
-#define AICA_CH_CMD_STOP    0x00000002
-#define AICA_CH_CMD_UPDATE  0x00000003
-
-/* Start values */
-#define AICA_CH_START_MASK  0x00300000
-
-#define AICA_CH_START_DELAY 0x00100000 /* Set params, but delay key-on */
-#define AICA_CH_START_SYNC  0x00200000 /* Set key-on for all selected channels */
-
-/* Update values */
-#define AICA_CH_UPDATE_MASK 0x000ff000
-
-#define AICA_CH_UPDATE_SET_FREQ 0x00001000 /* frequency     */
-#define AICA_CH_UPDATE_SET_VOL  0x00002000 /* volume        */
-#define AICA_CH_UPDATE_SET_PAN  0x00004000 /* panning       */
-
-/* Sample types */
-#define AICA_SM_8BIT    1
-#define AICA_SM_16BIT   0
-#define AICA_SM_ADPCM   2
-
+#include "aica_comm.h"
 
 /* This is where our SH-4/AICA comm variables go... */
 
diff --git a/aica/arm/aica_comm.h b/aica/arm/aica_comm.h
new file mode 100644 (file)
index 0000000..ba6d9af
--- /dev/null
@@ -0,0 +1,107 @@
+/* KallistiOS ##version##
+
+   aica_comm.h
+   Copyright (C) 2000-2002 Dan Potter
+
+   Structure and constant definitions for the SH-4/AICA interface. This file is
+   included from both the ARM and SH-4 sides of the fence.
+*/
+
+#ifndef __DC_SOUND_AICA_COMM_H
+#define __DC_SOUND_AICA_COMM_H
+
+#ifndef __ARCH_TYPES_H
+typedef unsigned long uint8;
+typedef unsigned long uint32;
+#endif
+
+/* Command queue; one of these for passing data from the SH-4 to the
+   AICA, and another for the other direction. If a command is written
+   to the queue and it is longer than the amount of space between the
+   head point and the queue size, the command will wrap around to
+   the beginning (i.e., queue commands _can_ be split up). */
+typedef struct aica_queue {
+    uint32      head;       /* Insertion point offset (in bytes) */
+    uint32      tail;       /* Removal point offset (in bytes) */
+    uint32      size;       /* Queue size (in bytes) */
+    uint32      valid;      /* 1 if the queue structs are valid */
+    uint32      process_ok; /* 1 if it's ok to process the data */
+    uint32      data;       /* Pointer to queue data buffer */
+} aica_queue_t;
+
+/* Command queue struct for commanding the AICA from the SH-4 */
+typedef struct aica_cmd {
+    uint32      size;       /* Command data size in dwords */
+    uint32      cmd;        /* Command ID */
+    uint32      timestamp;  /* When to execute the command (0 == now) */
+    uint32      cmd_id;     /* Command ID, for cmd/response pairs, or channel id */
+    uint32      misc[4];    /* Misc Parameters / Padding */
+    uint8       cmd_data[]; /* Command data */
+} aica_cmd_t;
+
+/* Maximum command size -- 256 dwords */
+#define AICA_CMD_MAX_SIZE   256
+
+/* This is the cmd_data for AICA_CMD_CHAN. Make this 16 dwords long
+   for two aica bus queues. */
+typedef struct aica_channel {
+    uint32      cmd;        /* Command ID */
+    uint32      base;       /* Sample base in RAM */
+    uint32      type;       /* (8/16bit/ADPCM) */
+    uint32      length;     /* Sample length */
+    uint32      loop;       /* Sample looping */
+    uint32      loopstart;  /* Sample loop start */
+    uint32      loopend;    /* Sample loop end */
+    uint32      freq;       /* Frequency */
+    uint32      vol;        /* Volume 0-255 */
+    uint32      pan;        /* Pan 0-255 */
+    uint32      pos;        /* Sample playback pos */
+    uint32      pad[5];     /* Padding */
+} aica_channel_t;
+
+/* Declare an aica_cmd_t big enough to hold an aica_channel_t
+   using temp name T, aica_cmd_t name CMDR, and aica_channel_t name CHANR */
+#define AICA_CMDSTR_CHANNEL(T, CMDR, CHANR) \
+    uint8   T[sizeof(aica_cmd_t) + sizeof(aica_channel_t)]; \
+    aica_cmd_t  * CMDR = (aica_cmd_t *)T; \
+    aica_channel_t  * CHANR = (aica_channel_t *)(CMDR->cmd_data);
+#define AICA_CMDSTR_CHANNEL_SIZE    ((sizeof(aica_cmd_t) + sizeof(aica_channel_t))/4)
+
+/* Command values (for aica_cmd_t) */
+#define AICA_CMD_NONE       0x00000000  /* No command (dummy packet)    */
+#define AICA_CMD_PING       0x00000001  /* Check for signs of life  */
+#define AICA_CMD_CHAN       0x00000002  /* Perform a wavetable action   */
+#define AICA_CMD_SYNC_CLOCK 0x00000003  /* Reset the millisecond clock  */
+
+/* Response values (for aica_cmd_t) */
+#define AICA_RESP_NONE      0x00000000
+#define AICA_RESP_PONG      0x00000001  /* Response to CMD_PING             */
+#define AICA_RESP_DBGPRINT  0x00000002  /* Entire payload is a null-terminated string   */
+
+/* Command values (for aica_channel_t commands) */
+#define AICA_CH_CMD_MASK    0x0000000f
+
+#define AICA_CH_CMD_NONE    0x00000000
+#define AICA_CH_CMD_START   0x00000001
+#define AICA_CH_CMD_STOP    0x00000002
+#define AICA_CH_CMD_UPDATE  0x00000003
+
+/* Start values */
+#define AICA_CH_START_MASK  0x00300000
+
+#define AICA_CH_START_DELAY 0x00100000 /* Set params, but delay key-on */
+#define AICA_CH_START_SYNC  0x00200000 /* Set key-on for all selected channels */
+
+/* Update values */
+#define AICA_CH_UPDATE_MASK 0x000ff000
+
+#define AICA_CH_UPDATE_SET_FREQ 0x00001000 /* frequency     */
+#define AICA_CH_UPDATE_SET_VOL  0x00002000 /* volume        */
+#define AICA_CH_UPDATE_SET_PAN  0x00004000 /* panning       */
+
+/* Sample types */
+#define AICA_SM_8BIT    1
+#define AICA_SM_16BIT   0
+#define AICA_SM_ADPCM   2
+
+#endif /* !__DC_SOUND_AICA_COMM_H */