1 #include <stdlib.h>
2 #include "ibm.h"
3 #include "device.h"
4 #include "io.h"
5 #include "sound.h"
6 
7 #include "sound_resid.h"
8 #include "sound_ssi2001.h"
9 
10 typedef struct ssi2001_t
11 {
12         void    *psid;
13         int16_t buffer[MAXSOUNDBUFLEN * 2];
14         int     pos;
15 } ssi2001_t;
16 
ssi2001_update(ssi2001_t * ssi2001)17 static void ssi2001_update(ssi2001_t *ssi2001)
18 {
19         if (ssi2001->pos >= sound_pos_global)
20                 return;
21 
22         sid_fillbuf(&ssi2001->buffer[ssi2001->pos], sound_pos_global - ssi2001->pos, ssi2001->psid);
23         ssi2001->pos = sound_pos_global;
24 }
25 
ssi2001_get_buffer(int32_t * buffer,int len,void * p)26 static void ssi2001_get_buffer(int32_t *buffer, int len, void *p)
27 {
28         ssi2001_t *ssi2001 = (ssi2001_t *)p;
29         int c;
30 
31         ssi2001_update(ssi2001);
32 
33         for (c = 0; c < len * 2; c++)
34                 buffer[c] += ssi2001->buffer[c >> 1] / 2;
35 
36         ssi2001->pos = 0;
37 }
38 
ssi2001_read(uint16_t addr,void * p)39 static uint8_t ssi2001_read(uint16_t addr, void *p)
40 {
41         ssi2001_t *ssi2001 = (ssi2001_t *)p;
42 
43         ssi2001_update(ssi2001);
44 
45         return sid_read(addr, p);
46 }
47 
ssi2001_write(uint16_t addr,uint8_t val,void * p)48 static void ssi2001_write(uint16_t addr, uint8_t val, void *p)
49 {
50         ssi2001_t *ssi2001 = (ssi2001_t *)p;
51 
52         ssi2001_update(ssi2001);
53         sid_write(addr, val, p);
54 }
55 
ssi2001_init()56 void *ssi2001_init()
57 {
58         ssi2001_t *ssi2001 = malloc(sizeof(ssi2001_t));
59         memset(ssi2001, 0, sizeof(ssi2001_t));
60 
61         pclog("ssi2001_init\n");
62         ssi2001->psid = sid_init();
63         sid_reset(ssi2001->psid);
64         io_sethandler(0x0280, 0x0020, ssi2001_read, NULL, NULL, ssi2001_write, NULL, NULL, ssi2001);
65         sound_add_handler(ssi2001_get_buffer, ssi2001);
66         return ssi2001;
67 }
68 
ssi2001_close(void * p)69 void ssi2001_close(void *p)
70 {
71         ssi2001_t *ssi2001 = (ssi2001_t *)p;
72 
73         sid_close(ssi2001->psid);
74 
75         free(ssi2001);
76 }
77 
78 device_t ssi2001_device =
79 {
80         "Innovation SSI-2001",
81         0,
82         ssi2001_init,
83         ssi2001_close,
84         NULL,
85         NULL,
86         NULL,
87         NULL
88 };
89