From 9837149c49ceabb347cdbe8e9a7900c528018acc Mon Sep 17 00:00:00 2001 From: Jason Self Date: Sat, 16 Jan 2021 09:12:41 -0800 Subject: [PATCH] aica: Update to the latest version --- WHENCE | 4 +- aica/arm/aica.c | 14 ++--- aica/arm/aica_cmd_iface.h | 95 +-------------------------------- aica/arm/aica_comm.h | 107 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 107 deletions(-) create mode 100644 aica/arm/aica_comm.h diff --git a/WHENCE b/WHENCE index 756de43..698ea32 100644 --- 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) diff --git a/aica/arm/aica.c b/aica/arm/aica.c index 2ff2ca1..411922b 100644 --- a/aica/arm/aica.c +++ b/aica/arm/aica.c @@ -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; } } diff --git a/aica/arm/aica_cmd_iface.h b/aica/arm/aica_cmd_iface.h index aba0a51..0c88580 100644 --- a/aica/arm/aica_cmd_iface.h +++ b/aica/arm/aica_cmd_iface.h @@ -10,100 +10,7 @@ #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 index 0000000..ba6d9af --- /dev/null +++ b/aica/arm/aica_comm.h @@ -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 */ -- 2.31.1