Run clang-format on all my new code

This commit is contained in:
RichardG867
2022-03-16 14:12:45 -03:00
parent 66e565000f
commit fd6646f21b
7 changed files with 1877 additions and 1857 deletions

View File

@@ -16,10 +16,10 @@
*/ */
#include <inttypes.h> #include <inttypes.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#ifdef _WIN32 #ifdef _WIN32
# include <winsock2.h> # include <winsock2.h>
@@ -39,24 +39,64 @@
#include <86box/plat.h> #include <86box/plat.h>
#include <86box/gdbstub.h> #include <86box/gdbstub.h>
#define FAST_RESPONSE(s) \
#define FAST_RESPONSE(s) strcpy(client->response, s); client->response_pos = sizeof(s); strcpy(client->response, s); \
client->response_pos = sizeof(s);
#define FAST_RESPONSE_HEX(s) gdbstub_client_respond_hex(client, (uint8_t *) s, sizeof(s)); #define FAST_RESPONSE_HEX(s) gdbstub_client_respond_hex(client, (uint8_t *) s, sizeof(s));
enum { enum {
GDB_SIGINT = 2, GDB_SIGINT = 2,
GDB_SIGTRAP = 5 GDB_SIGTRAP = 5
}; };
enum { enum {
GDB_REG_EAX = 0, GDB_REG_ECX, GDB_REG_EDX, GDB_REG_EBX, GDB_REG_ESP, GDB_REG_EBP, GDB_REG_ESI, GDB_REG_EDI, GDB_REG_EAX = 0,
GDB_REG_EIP, GDB_REG_EFLAGS, GDB_REG_ECX,
GDB_REG_CS, GDB_REG_SS, GDB_REG_DS, GDB_REG_ES, GDB_REG_FS, GDB_REG_GS, GDB_REG_FS_BASE, GDB_REG_GS_BASE, GDB_REG_EDX,
GDB_REG_CR0, GDB_REG_CR2, GDB_REG_CR3, GDB_REG_CR4, GDB_REG_EFER, GDB_REG_EBX,
GDB_REG_ST0, GDB_REG_ST1, GDB_REG_ST2, GDB_REG_ST3, GDB_REG_ST4, GDB_REG_ST5, GDB_REG_ST6, GDB_REG_ST7, GDB_REG_ESP,
GDB_REG_FCTRL, GDB_REG_FSTAT, GDB_REG_FTAG, GDB_REG_FISEG, GDB_REG_FIOFF, GDB_REG_FOSEG, GDB_REG_FOOFF, GDB_REG_FOP, GDB_REG_EBP,
GDB_REG_MM0, GDB_REG_MM1, GDB_REG_MM2, GDB_REG_MM3, GDB_REG_MM4, GDB_REG_MM5, GDB_REG_MM6, GDB_REG_MM7, GDB_REG_ESI,
GDB_REG_EDI,
GDB_REG_EIP,
GDB_REG_EFLAGS,
GDB_REG_CS,
GDB_REG_SS,
GDB_REG_DS,
GDB_REG_ES,
GDB_REG_FS,
GDB_REG_GS,
GDB_REG_FS_BASE,
GDB_REG_GS_BASE,
GDB_REG_CR0,
GDB_REG_CR2,
GDB_REG_CR3,
GDB_REG_CR4,
GDB_REG_EFER,
GDB_REG_ST0,
GDB_REG_ST1,
GDB_REG_ST2,
GDB_REG_ST3,
GDB_REG_ST4,
GDB_REG_ST5,
GDB_REG_ST6,
GDB_REG_ST7,
GDB_REG_FCTRL,
GDB_REG_FSTAT,
GDB_REG_FTAG,
GDB_REG_FISEG,
GDB_REG_FIOFF,
GDB_REG_FOSEG,
GDB_REG_FOOFF,
GDB_REG_FOP,
GDB_REG_MM0,
GDB_REG_MM1,
GDB_REG_MM2,
GDB_REG_MM3,
GDB_REG_MM4,
GDB_REG_MM5,
GDB_REG_MM6,
GDB_REG_MM7,
GDB_REG_MAX GDB_REG_MAX
}; };
@@ -107,13 +147,14 @@ gdbstub_log(const char *fmt, ...)
} }
} }
#else #else
#define gdbstub_log(fmt, ...) # define gdbstub_log(fmt, ...)
#endif #endif
static x86seg *segment_regs[] = {&cpu_state.seg_cs, &cpu_state.seg_ss, &cpu_state.seg_ds, &cpu_state.seg_es, &cpu_state.seg_fs, &cpu_state.seg_gs}; static x86seg *segment_regs[] = { &cpu_state.seg_cs, &cpu_state.seg_ss, &cpu_state.seg_ds, &cpu_state.seg_es, &cpu_state.seg_fs, &cpu_state.seg_gs };
static uint32_t *cr_regs[] = {&cpu_state.CR0.l, &cr2, &cr3, &cr4}; static uint32_t *cr_regs[] = { &cpu_state.CR0.l, &cr2, &cr3, &cr4 };
static void *fpu_regs[] = {&cpu_state.npxc, &cpu_state.npxs, NULL, &x87_pc_seg, &x87_pc_off, &x87_op_seg, &x87_op_off}; static void *fpu_regs[] = { &cpu_state.npxc, &cpu_state.npxs, NULL, &x87_pc_seg, &x87_pc_off, &x87_op_seg, &x87_op_off };
static const char target_xml[] = /* based on qemu's i386-32bit.xml */ static const char target_xml[] = /* based on qemu's i386-32bit.xml */
// clang-format off
"<?xml version=\"1.0\"?>" "<?xml version=\"1.0\"?>"
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">" "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target>" "<target>"
@@ -261,6 +302,7 @@ static const char target_xml[] = /* based on qemu's i386-32bit.xml */
"<reg name=\"mm7\" bitsize=\"64\" type=\"mmx\" group=\"mmx\"/>" "<reg name=\"mm7\" bitsize=\"64\" type=\"mmx\" group=\"mmx\"/>"
"</feature>" "</feature>"
"</target>"; "</target>";
// clang-format on
#ifdef _WIN32 #ifdef _WIN32
static WSADATA wsa; static WSADATA wsa;
@@ -279,7 +321,6 @@ static gdbstub_breakpoint_t *first_swbreak = NULL, *first_hwbreak = NULL,
int gdbstub_step = 0, gdbstub_next_asap = 0; int gdbstub_step = 0, gdbstub_next_asap = 0;
uint64_t gdbstub_watch_pages[(((uint32_t) -1) >> (MEM_GRANULARITY_BITS + 6)) + 1]; uint64_t gdbstub_watch_pages[(((uint32_t) -1) >> (MEM_GRANULARITY_BITS + 6)) + 1];
static void static void
gdbstub_break() gdbstub_break()
{ {
@@ -288,7 +329,6 @@ gdbstub_break()
gdbstub_step = GDBSTUB_BREAK; gdbstub_step = GDBSTUB_BREAK;
} }
static void static void
gdbstub_jump(uint32_t new_pc) gdbstub_jump(uint32_t new_pc)
{ {
@@ -302,7 +342,6 @@ gdbstub_jump(uint32_t new_pc)
flushmmucache(); flushmmucache();
} }
static inline int static inline int
gdbstub_hex_decode(int c) gdbstub_hex_decode(int c)
{ {
@@ -316,7 +355,6 @@ gdbstub_hex_decode(int c)
return 0; return 0;
} }
static inline int static inline int
gdbstub_hex_encode(int c) gdbstub_hex_encode(int c)
{ {
@@ -326,7 +364,6 @@ gdbstub_hex_encode(int c)
return c - 10 + 'A'; return c - 10 + 'A';
} }
static int static int
gdbstub_num_decode(char *p, int *dest, int mode) gdbstub_num_decode(char *p, int *dest, int mode)
{ {
@@ -415,7 +452,6 @@ gdbstub_num_decode(char *p, int *dest, int mode)
return 1; return 1;
} }
static int static int
gdbstub_client_read_word(gdbstub_client_t *client, int *dest) gdbstub_client_read_word(gdbstub_client_t *client, int *dest)
{ {
@@ -425,7 +461,6 @@ gdbstub_client_read_word(gdbstub_client_t *client, int *dest)
return p - q; return p - q;
} }
static int static int
gdbstub_client_read_hex(gdbstub_client_t *client, uint8_t *buf, int size) gdbstub_client_read_hex(gdbstub_client_t *client, uint8_t *buf, int size)
{ {
@@ -437,7 +472,6 @@ gdbstub_client_read_hex(gdbstub_client_t *client, uint8_t *buf, int size)
return pp - client->packet_pos; return pp - client->packet_pos;
} }
static int static int
gdbstub_client_read_string(gdbstub_client_t *client, char *buf, int size, char terminator) gdbstub_client_read_string(gdbstub_client_t *client, char *buf, int size, char terminator)
{ {
@@ -455,7 +489,6 @@ gdbstub_client_read_string(gdbstub_client_t *client, char *buf, int size, char t
return pp - client->packet_pos; return pp - client->packet_pos;
} }
static int static int
gdbstub_client_write_reg(int index, uint8_t *buf) gdbstub_client_write_reg(int index, uint8_t *buf)
{ {
@@ -539,7 +572,6 @@ gdbstub_client_write_reg(int index, uint8_t *buf)
return width; return width;
} }
static void static void
gdbstub_client_respond(gdbstub_client_t *client) gdbstub_client_respond(gdbstub_client_t *client)
{ {
@@ -558,11 +590,10 @@ gdbstub_client_respond(gdbstub_client_t *client)
#endif #endif
send(client->socket, "$", 1, 0); send(client->socket, "$", 1, 0);
send(client->socket, client->response, client->response_pos, 0); send(client->socket, client->response, client->response_pos, 0);
char response_cksum[3] = {'#', gdbstub_hex_encode((checksum >> 4) & 0x0f), gdbstub_hex_encode(checksum & 0x0f)}; char response_cksum[3] = { '#', gdbstub_hex_encode((checksum >> 4) & 0x0f), gdbstub_hex_encode(checksum & 0x0f) };
send(client->socket, response_cksum, sizeof(response_cksum), 0); send(client->socket, response_cksum, sizeof(response_cksum), 0);
} }
static void static void
gdbstub_client_respond_partial(gdbstub_client_t *client) gdbstub_client_respond_partial(gdbstub_client_t *client)
{ {
@@ -574,7 +605,6 @@ gdbstub_client_respond_partial(gdbstub_client_t *client)
thread_reset_event(client->response_event); thread_reset_event(client->response_event);
} }
static void static void
gdbstub_client_respond_hex(gdbstub_client_t *client, uint8_t *buf, int size) gdbstub_client_respond_hex(gdbstub_client_t *client, uint8_t *buf, int size)
{ {
@@ -584,7 +614,6 @@ gdbstub_client_respond_hex(gdbstub_client_t *client, uint8_t *buf, int size)
} }
} }
static int static int
gdbstub_client_read_reg(int index, uint8_t *buf) gdbstub_client_read_reg(int index, uint8_t *buf)
{ {
@@ -661,7 +690,6 @@ gdbstub_client_read_reg(int index, uint8_t *buf)
return width; return width;
} }
static void static void
gdbstub_client_packet(gdbstub_client_t *client) gdbstub_client_packet(gdbstub_client_t *client)
{ {
@@ -669,7 +697,7 @@ gdbstub_client_packet(gdbstub_client_t *client)
uint8_t rcv_checksum = 0, checksum = 0; uint8_t rcv_checksum = 0, checksum = 0;
#endif #endif
int i, j = 0, k = 0, l; int i, j = 0, k = 0, l;
uint8_t buf[10] = {0}; uint8_t buf[10] = { 0 };
char *p; char *p;
/* Validate checksum. */ /* Validate checksum. */
@@ -684,12 +712,12 @@ gdbstub_client_packet(gdbstub_client_t *client)
if (checksum != rcv_checksum) { if (checksum != rcv_checksum) {
/* Send negative acknowledgement. */ /* Send negative acknowledgement. */
#ifdef ENABLE_GDBSTUB_LOG # ifdef ENABLE_GDBSTUB_LOG
i = client->packet[953]; /* pclog_ex buffer too small */ i = client->packet[953]; /* pclog_ex buffer too small */
client->packet[953] = '\0'; client->packet[953] = '\0';
gdbstub_log("GDB Stub: Received packet with invalid checksum (expected %02X got %02X): %s\n", checksum, rcv_checksum, client->packet); gdbstub_log("GDB Stub: Received packet with invalid checksum (expected %02X got %02X): %s\n", checksum, rcv_checksum, client->packet);
client->packet[953] = i; client->packet[953] = i;
#endif # endif
send(client->socket, "-", 1, 0); send(client->socket, "-", 1, 0);
return; return;
} }
@@ -740,7 +768,8 @@ gdbstub_client_packet(gdbstub_client_t *client)
gdbstub_step = GDBSTUB_EXEC; gdbstub_step = GDBSTUB_EXEC;
/* Respond positively. */ /* Respond positively. */
ok: FAST_RESPONSE("OK"); ok:
FAST_RESPONSE("OK");
break; break;
case 'g': /* read all registers */ case 'g': /* read all registers */
@@ -761,7 +790,8 @@ ok: FAST_RESPONSE("OK");
case 'H': /* set thread */ case 'H': /* set thread */
/* Read operation type and thread ID. */ /* Read operation type and thread ID. */
if ((client->packet[1] == '\0') || (client->packet[2] == '\0')) { if ((client->packet[1] == '\0') || (client->packet[2] == '\0')) {
e22: FAST_RESPONSE("E22"); e22:
FAST_RESPONSE("E22");
break; break;
} }
@@ -869,7 +899,8 @@ e22: FAST_RESPONSE("E22");
case 'p': /* read register */ case 'p': /* read register */
/* Read register index. */ /* Read register index. */
if (!gdbstub_client_read_word(client, &j)) { if (!gdbstub_client_read_word(client, &j)) {
e14: FAST_RESPONSE("E14"); e14:
FAST_RESPONSE("E14");
break; break;
} }
@@ -902,19 +933,15 @@ e14: FAST_RESPONSE("E14");
/* Read the query type. */ /* Read the query type. */
client->packet_pos += gdbstub_client_read_string(client, client->response, sizeof(client->response) - 1, client->packet_pos += gdbstub_client_read_string(client, client->response, sizeof(client->response) - 1,
(client->packet[1] == 'R') ? ',' : ':') + 1; (client->packet[1] == 'R') ? ',' : ':')
+ 1;
/* Perform the query. */ /* Perform the query. */
if (!strcmp(client->response, "Supported")) { if (!strcmp(client->response, "Supported")) {
/* Go through the feature list and negate ones we don't support. */ /* Go through the feature list and negate ones we don't support. */
while ((client->response_pos < (sizeof(client->response) - 1)) && while ((client->response_pos < (sizeof(client->response) - 1)) && (i = gdbstub_client_read_string(client, &client->response[client->response_pos], sizeof(client->response) - client->response_pos - 1, ';'))) {
(i = gdbstub_client_read_string(client, &client->response[client->response_pos], sizeof(client->response) - client->response_pos - 1, ';'))) {
client->packet_pos += i + 1; client->packet_pos += i + 1;
if (strncmp(&client->response[client->response_pos], "PacketSize", 10) && if (strncmp(&client->response[client->response_pos], "PacketSize", 10) && strcmp(&client->response[client->response_pos], "swbreak") && strcmp(&client->response[client->response_pos], "hwbreak") && strncmp(&client->response[client->response_pos], "xmlRegisters", 12) && strcmp(&client->response[client->response_pos], "qXfer:features:read")) {
strcmp(&client->response[client->response_pos], "swbreak") &&
strcmp(&client->response[client->response_pos], "hwbreak") &&
strncmp(&client->response[client->response_pos], "xmlRegisters", 12) &&
strcmp(&client->response[client->response_pos], "qXfer:features:read")) {
gdbstub_log("GDB Stub: Feature \"%s\" is not supported\n", &client->response[client->response_pos]); gdbstub_log("GDB Stub: Feature \"%s\" is not supported\n", &client->response[client->response_pos]);
client->response_pos += i; client->response_pos += i;
client->response[client->response_pos++] = '-'; client->response[client->response_pos++] = '-';
@@ -945,7 +972,8 @@ e14: FAST_RESPONSE("E14");
/* Stop if the file wasn't found. */ /* Stop if the file wasn't found. */
if (!p) { if (!p) {
e00: FAST_RESPONSE("E00"); e00:
FAST_RESPONSE("E00");
break; break;
} }
@@ -1004,9 +1032,7 @@ e00: FAST_RESPONSE("E00");
l = (p[1] == 'n') ? p[2] : p[1]; l = (p[1] == 'n') ? p[2] : p[1];
/* Read optional I/O port. */ /* Read optional I/O port. */
if (!(p = strtok_r(NULL, " ", &strtok_save)) || if (!(p = strtok_r(NULL, " ", &strtok_save)) || !gdbstub_num_decode(p, &j, GDB_MODE_HEX) || (j < 0) || (j >= 65536))
!gdbstub_num_decode(p, &j, GDB_MODE_HEX) ||
(j < 0) || (j >= 65536))
j = client->last_io_base; j = client->last_io_base;
/* Read optional length. */ /* Read optional length. */
@@ -1064,7 +1090,8 @@ e00: FAST_RESPONSE("E00");
gdbstub_client_respond_hex(client, (uint8_t *) &client->packet, client->packet_pos); gdbstub_client_respond_hex(client, (uint8_t *) &client->packet, client->packet_pos);
break; break;
} else { } else {
unknown: FAST_RESPONSE_HEX("Unknown command\n"); unknown:
FAST_RESPONSE_HEX("Unknown command\n");
break; break;
} }
@@ -1201,7 +1228,6 @@ end:
gdbstub_client_respond(client); gdbstub_client_respond(client);
} }
static void static void
gdbstub_cpu_exec(int cycs) gdbstub_cpu_exec(int cycs)
{ {
@@ -1267,7 +1293,7 @@ gdbstub_cpu_exec(int cycs)
} }
/* Add register dump. */ /* Add register dump. */
uint8_t buf[10] = {0}; uint8_t buf[10] = { 0 };
int i, j, k; int i, j, k;
for (i = 0; i < GDB_REG_MAX; i++) { for (i = 0; i < GDB_REG_MAX; i++) {
if (i >= 0x10) if (i >= 0x10)
@@ -1329,7 +1355,6 @@ gdbstub_cpu_exec(int cycs)
in_gdbstub = 0; in_gdbstub = 0;
} }
static void static void
gdbstub_client_thread(void *priv) gdbstub_client_thread(void *priv)
{ {
@@ -1443,7 +1468,6 @@ gdbstub_client_thread(void *priv)
thread_release_mutex(client_list_mutex); thread_release_mutex(client_list_mutex);
} }
static void static void
gdbstub_server_thread(void *priv) gdbstub_server_thread(void *priv)
{ {
@@ -1493,7 +1517,6 @@ gdbstub_server_thread(void *priv)
free(client); free(client);
} }
void void
gdbstub_cpu_init() gdbstub_cpu_init()
{ {
@@ -1504,7 +1527,6 @@ gdbstub_cpu_init()
} }
} }
int int
gdbstub_instruction() gdbstub_instruction()
{ {
@@ -1535,7 +1557,6 @@ gdbstub_instruction()
return gdbstub_step - GDBSTUB_EXEC; return gdbstub_step - GDBSTUB_EXEC;
} }
int int
gdbstub_int3() gdbstub_int3()
{ {
@@ -1572,7 +1593,6 @@ gdbstub_int3()
return 0; return 0;
} }
void void
gdbstub_mem_access(uint32_t *addrs, int access) gdbstub_mem_access(uint32_t *addrs, int access)
{ {
@@ -1614,7 +1634,6 @@ gdbstub_mem_access(uint32_t *addrs, int access)
} }
} }
void void
gdbstub_init() gdbstub_init()
{ {
@@ -1655,7 +1674,6 @@ gdbstub_init()
gdbstub_step = GDBSTUB_BREAK; gdbstub_step = GDBSTUB_BREAK;
} }
void void
gdbstub_close() gdbstub_close()
{ {

View File

@@ -15,7 +15,7 @@
* Copyright 2022 RichardG. * Copyright 2022 RichardG.
*/ */
#ifndef EMU_GDBSTUB_H #ifndef EMU_GDBSTUB_H
# define EMU_GDBSTUB_H #define EMU_GDBSTUB_H
#include <86box/mem.h> #include <86box/mem.h>
#define GDBSTUB_MEM_READ 0 #define GDBSTUB_MEM_READ 0
@@ -35,18 +35,18 @@ enum {
#ifdef USE_GDBSTUB #ifdef USE_GDBSTUB
#define GDBSTUB_MEM_ACCESS(addr, access, width) \ # define GDBSTUB_MEM_ACCESS(addr, access, width) \
uint32_t gdbstub_page = addr >> MEM_GRANULARITY_BITS; \ uint32_t gdbstub_page = addr >> MEM_GRANULARITY_BITS; \
if (gdbstub_watch_pages[gdbstub_page >> 6] & (1 << (gdbstub_page & 63)) || (addr == 0xb8dd4)) { \ if (gdbstub_watch_pages[gdbstub_page >> 6] & (1 << (gdbstub_page & 63))) { \
uint32_t gdbstub_addrs[width]; \ uint32_t gdbstub_addrs[width]; \
for (int gdbstub_i = 0; gdbstub_i < width; gdbstub_i++) \ for (int gdbstub_i = 0; gdbstub_i < width; gdbstub_i++) \
gdbstub_addrs[gdbstub_i] = addr + gdbstub_i; \ gdbstub_addrs[gdbstub_i] = addr + gdbstub_i; \
gdbstub_mem_access(gdbstub_addrs, access | width); \ gdbstub_mem_access(gdbstub_addrs, access | width); \
} }
#define GDBSTUB_MEM_ACCESS_FAST(addrs, access, width) \ # define GDBSTUB_MEM_ACCESS_FAST(addrs, access, width) \
uint32_t gdbstub_page = addr >> MEM_GRANULARITY_BITS; \ uint32_t gdbstub_page = addr >> MEM_GRANULARITY_BITS; \
if (gdbstub_watch_pages[gdbstub_page >> 6] & (1 << (gdbstub_page & 63)) || (addr == 0xb8dd4)) \ if (gdbstub_watch_pages[gdbstub_page >> 6] & (1 << (gdbstub_page & 63))) \
gdbstub_mem_access(addrs, access | width); gdbstub_mem_access(addrs, access | width);
extern int gdbstub_step, gdbstub_next_asap; extern int gdbstub_step, gdbstub_next_asap;
@@ -61,17 +61,17 @@ extern void gdbstub_close();
#else #else
#define GDBSTUB_MEM_ACCESS(addr, access, width) # define GDBSTUB_MEM_ACCESS(addr, access, width)
#define GDBSTUB_MEM_ACCESS_FAST(addrs, access, width) # define GDBSTUB_MEM_ACCESS_FAST(addrs, access, width)
#define gdbstub_step 0 # define gdbstub_step 0
#define gdbstub_next_asap 0 # define gdbstub_next_asap 0
#define gdbstub_cpu_init() # define gdbstub_cpu_init()
#define gdbstub_instruction() 0 # define gdbstub_instruction() 0
#define gdbstub_int3() 0 # define gdbstub_int3() 0
#define gdbstub_init() # define gdbstub_init()
#define gdbstub_close() # define gdbstub_close()
#endif #endif

View File

@@ -437,15 +437,15 @@ ad1848_process_alaw(uint8_t byte)
int seg = (byte & 0x70) >> 4; int seg = (byte & 0x70) >> 4;
switch (seg) { switch (seg) {
case 0: case 0:
dec += 0x8; dec |= 0x8;
break; break;
case 1: case 1:
dec += 0x108; dec |= 0x108;
break; break;
default: default:
dec += 0x108; dec |= 0x108;
dec <<= seg - 1; dec <<= seg - 1;
break; break;
} }

View File

@@ -35,7 +35,6 @@
#include <86box/nmi.h> #include <86box/nmi.h>
#include <86box/ui.h> #include <86box/ui.h>
enum { enum {
/* [23:16] = reg 0F [7:0] (reg 0C [31:24]) /* [23:16] = reg 0F [7:0] (reg 0C [31:24])
[13] = onboard flag [13] = onboard flag
@@ -87,7 +86,6 @@ typedef struct _cmi8x38_ {
int master_vol_l, master_vol_r, cd_vol_l, cd_vol_r; int master_vol_l, master_vol_r, cd_vol_l, cd_vol_r;
} cmi8x38_t; } cmi8x38_t;
#ifdef ENABLE_CMI8X38_LOG #ifdef ENABLE_CMI8X38_LOG
int cmi8x38_do_log = ENABLE_CMI8X38_LOG; int cmi8x38_do_log = ENABLE_CMI8X38_LOG;
@@ -103,17 +101,15 @@ cmi8x38_log(const char *fmt, ...)
} }
} }
#else #else
#define cmi8x38_log(fmt, ...) # define cmi8x38_log(fmt, ...)
#endif #endif
static const double freqs[] = {5512.0, 11025.0, 22050.0, 44100.0, 8000.0, 16000.0, 32000.0, 48000.0}; static const double freqs[] = { 5512.0, 11025.0, 22050.0, 44100.0, 8000.0, 16000.0, 32000.0, 48000.0 };
static const uint16_t opl_ports_cmi8738[] = {0x388, 0x3c8, 0x3e0, 0x3e8}; static const uint16_t opl_ports_cmi8738[] = { 0x388, 0x3c8, 0x3e0, 0x3e8 };
static void cmi8x38_dma_process(void *priv); static void cmi8x38_dma_process(void *priv);
static void cmi8x38_speed_changed(void *priv); static void cmi8x38_speed_changed(void *priv);
static void static void
cmi8x38_update_irqs(cmi8x38_t *dev) cmi8x38_update_irqs(cmi8x38_t *dev)
{ {
@@ -128,7 +124,6 @@ cmi8x38_update_irqs(cmi8x38_t *dev)
} }
} }
static void static void
cmi8x38_mpu_irq_update(void *priv, int set) cmi8x38_mpu_irq_update(void *priv, int set)
{ {
@@ -140,7 +135,6 @@ cmi8x38_mpu_irq_update(void *priv, int set)
cmi8x38_update_irqs(dev); cmi8x38_update_irqs(dev);
} }
static int static int
cmi8x38_mpu_irq_pending(void *priv) cmi8x38_mpu_irq_pending(void *priv)
{ {
@@ -148,7 +142,6 @@ cmi8x38_mpu_irq_pending(void *priv)
return dev->io_regs[0x12] & 0x01; return dev->io_regs[0x12] & 0x01;
} }
static void static void
cmi8x38_sb_irq_update(void *priv, int set) cmi8x38_sb_irq_update(void *priv, int set)
{ {
@@ -162,7 +155,6 @@ cmi8x38_sb_irq_update(void *priv, int set)
cmi8x38_update_irqs(dev); cmi8x38_update_irqs(dev);
} }
static int static int
cmi8x38_sb_dma_post(cmi8x38_t *dev, uint16_t *addr, uint16_t *count, int channel) cmi8x38_sb_dma_post(cmi8x38_t *dev, uint16_t *addr, uint16_t *count, int channel)
{ {
@@ -173,10 +165,11 @@ cmi8x38_sb_dma_post(cmi8x38_t *dev, uint16_t *addr, uint16_t *count, int channel
/* Copy TDMA registers to DMA on CMI8738+. Everything so far suggests that /* Copy TDMA registers to DMA on CMI8738+. Everything so far suggests that
those chips use PCI bus mastering to directly write to the DMA registers. */ those chips use PCI bus mastering to directly write to the DMA registers. */
#if 0 /* TSRs don't set ENWR8237, except for the patched C3DPCI - does that bit have no effect? */ #if 0 /* TSRs don't set ENWR8237, except for the patched C3DPCI - does that bit have no effect? */
if ((dev->type != CMEDIA_CMI8338) && (dev->io_regs[0x17] & 0x10)) { if ((dev->type != CMEDIA_CMI8338) && (dev->io_regs[0x17] & 0x10))
#else #else
if (dev->type != CMEDIA_CMI8338) { if (dev->type != CMEDIA_CMI8338)
#endif #endif
{
if (channel & 4) if (channel & 4)
dma[channel].ab = (dma[channel].ab & 0xfffe0000) | ((*addr) << 1); dma[channel].ab = (dma[channel].ab & 0xfffe0000) | ((*addr) << 1);
else else
@@ -209,7 +202,6 @@ cmi8x38_sb_dma_post(cmi8x38_t *dev, uint16_t *addr, uint16_t *count, int channel
return 0; return 0;
} }
static int static int
cmi8x38_sb_dma_readb(void *priv) cmi8x38_sb_dma_readb(void *priv)
{ {
@@ -233,7 +225,6 @@ cmi8x38_sb_dma_readb(void *priv)
return ret; return ret;
} }
static int static int
cmi8x38_sb_dma_readw(void *priv) cmi8x38_sb_dma_readw(void *priv)
{ {
@@ -257,7 +248,6 @@ cmi8x38_sb_dma_readw(void *priv)
return ret; return ret;
} }
static int static int
cmi8x38_sb_dma_writeb(void *priv, uint8_t val) cmi8x38_sb_dma_writeb(void *priv, uint8_t val)
{ {
@@ -281,7 +271,6 @@ cmi8x38_sb_dma_writeb(void *priv, uint8_t val)
return 0; return 0;
} }
static int static int
cmi8x38_sb_dma_writew(void *priv, uint16_t val) cmi8x38_sb_dma_writew(void *priv, uint16_t val)
{ {
@@ -305,7 +294,6 @@ cmi8x38_sb_dma_writew(void *priv, uint16_t val)
return 0; return 0;
} }
static void static void
cmi8x38_dma_write(uint16_t addr, uint8_t val, void *priv) cmi8x38_dma_write(uint16_t addr, uint8_t val, void *priv)
{ {
@@ -364,7 +352,6 @@ cmi8x38_dma_mask_write(uint16_t addr, uint8_t val, void *priv)
dev->prev_mask = dma_m; dev->prev_mask = dma_m;
} }
static void static void
cmi8338_io_trap(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) cmi8338_io_trap(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
{ {
@@ -388,7 +375,6 @@ cmi8338_io_trap(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
nmi = 1; nmi = 1;
} }
static uint8_t static uint8_t
cmi8x38_sb_mixer_read(uint16_t addr, void *priv) cmi8x38_sb_mixer_read(uint16_t addr, void *priv)
{ {
@@ -407,7 +393,6 @@ cmi8x38_sb_mixer_read(uint16_t addr, void *priv)
return ret; return ret;
} }
static void static void
cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv) cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv)
{ {
@@ -472,7 +457,6 @@ cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv)
} }
} }
static void static void
cmi8x38_remap_sb(cmi8x38_t *dev) cmi8x38_remap_sb(cmi8x38_t *dev)
{ {
@@ -508,7 +492,6 @@ cmi8x38_remap_sb(cmi8x38_t *dev)
} }
} }
static void static void
cmi8x38_remap_opl(cmi8x38_t *dev) cmi8x38_remap_opl(cmi8x38_t *dev)
{ {
@@ -530,7 +513,6 @@ cmi8x38_remap_opl(cmi8x38_t *dev)
} }
} }
static void static void
cmi8x38_remap_mpu(cmi8x38_t *dev) cmi8x38_remap_mpu(cmi8x38_t *dev)
{ {
@@ -550,7 +532,6 @@ cmi8x38_remap_mpu(cmi8x38_t *dev)
mpu401_change_addr(dev->sb->mpu, dev->mpu_base); mpu401_change_addr(dev->sb->mpu, dev->mpu_base);
} }
static void static void
cmi8x38_remap_traps(cmi8x38_t *dev) cmi8x38_remap_traps(cmi8x38_t *dev)
{ {
@@ -560,7 +541,6 @@ cmi8x38_remap_traps(cmi8x38_t *dev)
io_trap_remap(dev->io_traps[TRAP_PIC], (dev->io_regs[0x04] & 0x01) && (dev->io_regs[0x17] & 0x01), 0x0020, 2); io_trap_remap(dev->io_traps[TRAP_PIC], (dev->io_regs[0x04] & 0x01) && (dev->io_regs[0x17] & 0x01), 0x0020, 2);
} }
static void static void
cmi8x38_start_playback(cmi8x38_t *dev) cmi8x38_start_playback(cmi8x38_t *dev)
{ {
@@ -577,7 +557,6 @@ cmi8x38_start_playback(cmi8x38_t *dev)
dev->dma[1].playback_enabled = i; dev->dma[1].playback_enabled = i;
} }
static uint8_t static uint8_t
cmi8x38_read(uint16_t addr, void *priv) cmi8x38_read(uint16_t addr, void *priv)
{ {
@@ -586,7 +565,8 @@ cmi8x38_read(uint16_t addr, void *priv)
uint8_t ret; uint8_t ret;
switch (addr) { switch (addr) {
case 0x22: case 0x23: case 0x22:
case 0x23:
ret = cmi8x38_sb_mixer_read(addr ^ 1, dev); ret = cmi8x38_sb_mixer_read(addr ^ 1, dev);
break; break;
@@ -604,40 +584,49 @@ cmi8x38_read(uint16_t addr, void *priv)
ret = opl3_read(addr, &dev->sb->opl); ret = opl3_read(addr, &dev->sb->opl);
break; break;
case 0x80: case 0x88: case 0x80:
case 0x88:
ret = dev->dma[(addr & 0x78) >> 3].sample_ptr; ret = dev->dma[(addr & 0x78) >> 3].sample_ptr;
break; break;
case 0x81: case 0x89: case 0x81:
case 0x89:
ret = dev->dma[(addr & 0x78) >> 3].sample_ptr >> 8; ret = dev->dma[(addr & 0x78) >> 3].sample_ptr >> 8;
break; break;
case 0x82: case 0x8a: case 0x82:
case 0x8a:
ret = dev->dma[(addr & 0x78) >> 3].sample_ptr >> 16; ret = dev->dma[(addr & 0x78) >> 3].sample_ptr >> 16;
break; break;
case 0x83: case 0x8b: case 0x83:
case 0x8b:
ret = dev->dma[(addr & 0x78) >> 3].sample_ptr >> 24; ret = dev->dma[(addr & 0x78) >> 3].sample_ptr >> 24;
break; break;
case 0x84: case 0x8c: case 0x84:
case 0x8c:
ret = dev->dma[(addr & 0x78) >> 3].frame_count_dma; ret = dev->dma[(addr & 0x78) >> 3].frame_count_dma;
break; break;
case 0x85: case 0x8d: case 0x85:
case 0x8d:
ret = dev->dma[(addr & 0x78) >> 3].frame_count_dma >> 8; ret = dev->dma[(addr & 0x78) >> 3].frame_count_dma >> 8;
break; break;
case 0x86: case 0x8e: case 0x86:
case 0x8e:
ret = dev->dma[(addr & 0x78) >> 3].sample_count_out >> 2; ret = dev->dma[(addr & 0x78) >> 3].sample_count_out >> 2;
break; break;
case 0x87: case 0x8f: case 0x87:
case 0x8f:
ret = dev->dma[(addr & 0x78) >> 3].sample_count_out >> 10; ret = dev->dma[(addr & 0x78) >> 3].sample_count_out >> 10;
break; break;
default: default:
io_reg: ret = dev->io_regs[addr]; io_reg:
ret = dev->io_regs[addr];
break; break;
} }
@@ -645,7 +634,6 @@ io_reg: ret = dev->io_regs[addr];
return ret; return ret;
} }
static void static void
cmi8x38_write(uint16_t addr, uint8_t val, void *priv) cmi8x38_write(uint16_t addr, uint8_t val, void *priv)
{ {
@@ -732,7 +720,8 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv)
cmi8x38_speed_changed(dev); cmi8x38_speed_changed(dev);
break; break;
case 0x0a: case 0x0b: case 0x0a:
case 0x0b:
if (dev->type == CMEDIA_CMI8338) if (dev->type == CMEDIA_CMI8338)
return; return;
else else
@@ -846,7 +835,8 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv)
dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2 : SB16; dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2 : SB16;
break; break;
case 0x22: case 0x23: case 0x22:
case 0x23:
cmi8x38_sb_mixer_write(addr ^ 1, val, dev); cmi8x38_sb_mixer_write(addr ^ 1, val, dev);
return; return;
@@ -886,8 +876,10 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv)
val &= 0x10; val &= 0x10;
break; break;
case 0x25: case 0x26: case 0x25:
case 0x70: case 0x71: case 0x26:
case 0x70:
case 0x71:
case 0x80 ... 0x8f: case 0x80 ... 0x8f:
break; break;
@@ -898,7 +890,6 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv)
dev->io_regs[addr] = val; dev->io_regs[addr] = val;
} }
static void static void
cmi8x38_remap(cmi8x38_t *dev) cmi8x38_remap(cmi8x38_t *dev)
{ {
@@ -912,7 +903,6 @@ cmi8x38_remap(cmi8x38_t *dev)
io_sethandler(dev->io_base, 256, cmi8x38_read, NULL, NULL, cmi8x38_write, NULL, NULL, dev); io_sethandler(dev->io_base, 256, cmi8x38_read, NULL, NULL, cmi8x38_write, NULL, NULL, dev);
} }
static uint8_t static uint8_t
cmi8x38_pci_read(int func, int addr, void *priv) cmi8x38_pci_read(int func, int addr, void *priv)
{ {
@@ -927,7 +917,6 @@ cmi8x38_pci_read(int func, int addr, void *priv)
return ret; return ret;
} }
static void static void
cmi8x38_pci_write(int func, int addr, uint8_t val, void *priv) cmi8x38_pci_write(int func, int addr, uint8_t val, void *priv)
{ {
@@ -957,7 +946,10 @@ cmi8x38_pci_write(int func, int addr, uint8_t val, void *priv)
cmi8x38_remap(dev); cmi8x38_remap(dev);
break; break;
case 0x2c: case 0x2d: case 0x2e: case 0x2f: case 0x2c:
case 0x2d:
case 0x2e:
case 0x2f:
if (!(dev->io_regs[0x1a] & 0x01)) if (!(dev->io_regs[0x1a] & 0x01))
return; return;
break; break;
@@ -969,7 +961,8 @@ cmi8x38_pci_write(int func, int addr, uint8_t val, void *priv)
return; return;
break; break;
case 0x0c: case 0x0d: case 0x0c:
case 0x0d:
case 0x3c: case 0x3c:
break; break;
@@ -980,7 +973,6 @@ cmi8x38_pci_write(int func, int addr, uint8_t val, void *priv)
dev->pci_regs[addr] = val; dev->pci_regs[addr] = val;
} }
static void static void
cmi8x38_update(cmi8x38_t *dev, cmi8x38_dma_t *dma) cmi8x38_update(cmi8x38_t *dev, cmi8x38_dma_t *dma)
{ {
@@ -989,12 +981,11 @@ cmi8x38_update(cmi8x38_t *dev, cmi8x38_dma_t *dma)
r = (dma->out_fr * mixer->voice_r) * mixer->master_r; r = (dma->out_fr * mixer->voice_r) * mixer->master_r;
for (; dma->pos < sound_pos_global; dma->pos++) { for (; dma->pos < sound_pos_global; dma->pos++) {
dma->buffer[dma->pos*2] = l; dma->buffer[dma->pos * 2] = l;
dma->buffer[dma->pos*2 + 1] = r; dma->buffer[dma->pos * 2 + 1] = r;
} }
} }
static void static void
cmi8x38_dma_process(void *priv) cmi8x38_dma_process(void *priv)
{ {
@@ -1069,7 +1060,6 @@ cmi8x38_dma_process(void *priv)
} }
} }
static void static void
cmi8x38_poll(void *priv) cmi8x38_poll(void *priv)
{ {
@@ -1185,7 +1175,7 @@ cmi8x38_poll(void *priv)
dma->fifo_pos += 2; dma->fifo_pos += 2;
dma->out_c = *((uint16_t *) &dma->fifo[dma->fifo_pos & (sizeof(dma->fifo) - 1)]); dma->out_c = *((uint16_t *) &dma->fifo[dma->fifo_pos & (sizeof(dma->fifo) - 1)]);
dma->fifo_pos += 2; dma->fifo_pos += 2;
dma->out_lfe= *((uint16_t *) &dma->fifo[dma->fifo_pos & (sizeof(dma->fifo) - 1)]); dma->out_lfe = *((uint16_t *) &dma->fifo[dma->fifo_pos & (sizeof(dma->fifo) - 1)]);
dma->fifo_pos += 2; dma->fifo_pos += 2;
dma->sample_count_out -= 12; dma->sample_count_out -= 12;
return; return;
@@ -1207,7 +1197,6 @@ n4spk3d:
} }
} }
static void static void
cmi8x38_get_buffer(int32_t *buffer, int len, void *priv) cmi8x38_get_buffer(int32_t *buffer, int len, void *priv)
{ {
@@ -1229,7 +1218,6 @@ cmi8x38_get_buffer(int32_t *buffer, int len, void *priv)
dev->dma[0].pos = dev->dma[1].pos = 0; dev->dma[0].pos = dev->dma[1].pos = 0;
} }
static void static void
cmi8x38_speed_changed(void *priv) cmi8x38_speed_changed(void *priv)
{ {
@@ -1251,10 +1239,18 @@ cmi8x38_speed_changed(void *priv)
bits take precedence over any configured sample rate. 128K with both bits take precedence over any configured sample rate. 128K with both
doubling bits set is also supported there, but that's for newer chips. */ doubling bits set is also supported there, but that's for newer chips. */
switch (dsr & 0x03) { switch (dsr & 0x03) {
case 0x01: freq = 88200.0; break; case 0x01:
case 0x02: freq = 96000.0; break; freq = 88200.0;
case 0x03: freq = 128000.0; break; break;
default: freq = freqs[freqreg & 0x07]; break; case 0x02:
freq = 96000.0;
break;
case 0x03:
freq = 128000.0;
break;
default:
freq = freqs[freqreg & 0x07];
break;
} }
/* Set polling timer period. */ /* Set polling timer period. */
@@ -1263,7 +1259,8 @@ cmi8x38_speed_changed(void *priv)
/* Calculate channel count and set DMA timer period. */ /* Calculate channel count and set DMA timer period. */
if ((dev->type == CMEDIA_CMI8338) || (i == 0)) { if ((dev->type == CMEDIA_CMI8338) || (i == 0)) {
stereo: dev->dma[i].channels = 2; stereo:
dev->dma[i].channels = 2;
} else { } else {
if (chfmt45 & 0x80) if (chfmt45 & 0x80)
dev->dma[i].channels = (chfmt6 & 0x80) ? 6 : 5; dev->dma[i].channels = (chfmt6 & 0x80) ? 6 : 5;
@@ -1288,7 +1285,6 @@ stereo: dev->dma[i].channels = 2;
#endif #endif
} }
static void static void
cmi8x38_reset(void *priv) cmi8x38_reset(void *priv)
{ {
@@ -1296,18 +1292,25 @@ cmi8x38_reset(void *priv)
/* Reset PCI configuration registers. */ /* Reset PCI configuration registers. */
memset(dev->pci_regs, 0, sizeof(dev->pci_regs)); memset(dev->pci_regs, 0, sizeof(dev->pci_regs));
dev->pci_regs[0x00] = 0xf6; dev->pci_regs[0x01] = 0x13; dev->pci_regs[0x00] = 0xf6;
dev->pci_regs[0x02] = dev->type; dev->pci_regs[0x03] = 0x01; dev->pci_regs[0x01] = 0x13;
dev->pci_regs[0x06] = (dev->type == CMEDIA_CMI8338) ? 0x80 : 0x10; dev->pci_regs[0x07] = 0x02; dev->pci_regs[0x02] = dev->type;
dev->pci_regs[0x03] = 0x01;
dev->pci_regs[0x06] = (dev->type == CMEDIA_CMI8338) ? 0x80 : 0x10;
dev->pci_regs[0x07] = 0x02;
dev->pci_regs[0x08] = 0x10; dev->pci_regs[0x08] = 0x10;
dev->pci_regs[0x0a] = 0x01; dev->pci_regs[0x0b] = 0x04; dev->pci_regs[0x0a] = 0x01;
dev->pci_regs[0x0b] = 0x04;
dev->pci_regs[0x0d] = 0x20; dev->pci_regs[0x0d] = 0x20;
dev->pci_regs[0x10] = 0x01; dev->pci_regs[0x10] = 0x01;
dev->pci_regs[0x2c] = 0xf6; dev->pci_regs[0x2d] = 0x13; dev->pci_regs[0x2c] = 0xf6;
dev->pci_regs[0x2d] = 0x13;
if (dev->type == CMEDIA_CMI8338) { if (dev->type == CMEDIA_CMI8338) {
dev->pci_regs[0x2e] = 0xff; dev->pci_regs[0x2f] = 0xff; dev->pci_regs[0x2e] = 0xff;
dev->pci_regs[0x2f] = 0xff;
} else { } else {
dev->pci_regs[0x2e] = dev->type; dev->pci_regs[0x2f] = 0x01; dev->pci_regs[0x2e] = dev->type;
dev->pci_regs[0x2f] = 0x01;
dev->pci_regs[0x34] = 0x40; dev->pci_regs[0x34] = 0x40;
} }
dev->pci_regs[0x3d] = 0x01; dev->pci_regs[0x3d] = 0x01;
@@ -1342,7 +1345,6 @@ cmi8x38_reset(void *priv)
sb_ct1745_mixer_reset(dev->sb); sb_ct1745_mixer_reset(dev->sb);
} }
static void * static void *
cmi8x38_init(const device_t *info) cmi8x38_init(const device_t *info)
{ {
@@ -1405,7 +1407,6 @@ cmi8x38_init(const device_t *info)
return dev; return dev;
} }
static void static void
cmi8x38_close(void *priv) cmi8x38_close(void *priv)
{ {
@@ -1420,14 +1421,18 @@ cmi8x38_close(void *priv)
} }
static const device_config_t cmi8x38_config[] = { static const device_config_t cmi8x38_config[] = {
{ "receive_input", "Receive input (MPU-401)", CONFIG_BINARY, "", 1 }, // clang-format off
{"receive_input", "Receive input (MPU-401)", CONFIG_BINARY, "", 1 },
{ "", "", -1 } { "", "", -1 }
// clang-format on
}; };
static const device_config_t cmi8738_config[] = { static const device_config_t cmi8738_config[] = {
// clang-format off
{ "six_channel", "6CH variant (6-channel)", CONFIG_BINARY, "", 1 }, { "six_channel", "6CH variant (6-channel)", CONFIG_BINARY, "", 1 },
{ "receive_input", "Receive input (MPU-401)", CONFIG_BINARY, "", 1 }, { "receive_input", "Receive input (MPU-401)", CONFIG_BINARY, "", 1 },
{ "", "", -1 } { "", "", -1 }
// clang-format on
}; };
const device_t cmi8338_device = { const device_t cmi8338_device = {

View File

@@ -1841,7 +1841,6 @@ sb_16_compat_init(const device_t *info)
return sb; return sb;
} }
static int static int
sb_awe32_available() sb_awe32_available()
{ {
@@ -2564,8 +2563,7 @@ const device_t sb_16_pnp_device = {
.config = sb_16_pnp_config .config = sb_16_pnp_config
}; };
const device_t sb_16_compat_device = const device_t sb_16_compat_device = {
{
.name = "Sound Blaster 16 (Compatibility)", .name = "Sound Blaster 16 (Compatibility)",
.internal_name = "sb16_compat", .internal_name = "sb16_compat",
.flags = DEVICE_ISA | DEVICE_AT, .flags = DEVICE_ISA | DEVICE_AT,
@@ -2579,8 +2577,7 @@ const device_t sb_16_compat_device =
.config = NULL .config = NULL
}; };
const device_t sb_16_compat_nompu_device = const device_t sb_16_compat_nompu_device = {
{
.name = "Sound Blaster 16 (Compatibility - MPU-401 Off)", .name = "Sound Blaster 16 (Compatibility - MPU-401 Off)",
.internal_name = "sb16_compat", .internal_name = "sb16_compat",
.flags = DEVICE_ISA | DEVICE_AT, .flags = DEVICE_ISA | DEVICE_AT,
@@ -2589,7 +2586,7 @@ const device_t sb_16_compat_nompu_device =
.close = sb_close, .close = sb_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed =sb_speed_changed, .speed_changed = sb_speed_changed,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };