Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
sid.h
Go to the documentation of this file.
1 /*
2  * This source is a modifed version of sidengine.c from here: https://github.com/wothke/websid
3  * Modification is mainly about killing the not-SID related parts, and making emulation modular,
4  * ie introducing a way to allow to emulate more SIDs through the SidEmulation structure pointer.
5  * Otherwise it should be the same. Sorry, I am just lame with sound things, the modularization
6  * can be done in a better way, ie some things should not be per SID stuff, etc.
7  * Modifications done by: Gabor Lenart (aka LGB) lgblgblgb@gmail.com http://lgb.hu/
8  * Mainly for having *some* sound for my primitive Commodore 65 emulator :)
9  * https://github.com/lgblgblgb/xclcd
10  *
11  * ---- NOW THE ORIGINAL COMMENT HEADER FOLLOWS ----
12  *
13  * This file is largely the original file from the "TinySid for Linux" distribution.
14  *
15  * <p>TinySid (c) 1999-2012 T. Hinrichs, R. Sinsch
16  *
17  * <p>It was updated by merging in the latest "Rockbox" version (This noticably fixed playback problems with
18  * "Yie Ar Kung Fu"..) and by applying fixes contributed by Markus Gritsch. Unfortunately a revision history of the old
19  * TinySid codebase does not seem to exist.. so we'll probably never know what was used for the TinySid Windows executable and
20  * why it is the only version that correctly plays Electric_Girls.sid..)
21  * <p>In this file I deliberately kept the "naming conventions" used in the original TinySID code - to ease future merging
22  * of potential TinySid fixes (consequently there is a mismatch with the conventions that I am using in my own code..)
23  *
24  * <p>My additions here are:
25  * <ol>
26  * <li>fixed PSID digi playback volume (was originally too low)
27  * <li>correct cycle-time calculation for ALL 6510 op codes (also illegal ones)
28  * <li>added impls for illegal 6510 op codes, fixed errors in V-flag calculation, added handling for 6510 addressing "bugs"
29  * <li>poor man's VIC and CIA handling
30  * <li>"cycle limit" feature used to interrupt emulation runs (e.g. main prog can now be suspended/continued)
31  * <li>Poor man's "combined pulse/triangle waveform" impl to allow playback of songs like Kentilla.sid.
32  * <li>added RSID digi playback support (D418 based as well as "pulse width modulation" based): it is a "special feature" of
33  * this implementation that regular SID emulation is performed somewhat independently from the handling of digi samples, i.e. playback
34  * of digi samples is tracked separately (for main, IRQ and NMI) and the respective digi samples are then merged with the regular SID
35  * output as some kind of postprocessing step
36  * <li> replaced original "envelope generator" impl with a more realistic one (incl. "ADSR-bug" handling)
37  * </ol>
38  *
39  * FIXME: refactor CPU and SID emulation into separate files..
40  *
41  * known limitation: basic-ROM specific handling not implemented...
42  *
43  * <p>Notice: if you have questions regarding the details of the below SID emulation, then you should better get in touch with R.Sinsch :-)
44  *
45  * <p>Tiny'R'Sid add-ons (c) 2015 J.Wothke
46  *
47  * Terms of Use: This software is licensed under a CC BY-NC-SA
48  * (http://creativecommons.org/licenses/by-nc-sa/4.0/).
49  */
50 
51 #ifndef __SIDENGINE_H_IS_INCLUDED
52 #define __SIDENGINE_H_IS_INCLUDED
53 
54 #include <SDL_atomic.h>
55 
56 // 0x38: supposedly DC level for MOS6581 (whereas it would be 0x80 for the "crappy new chip")
57 #define SID_DC_LEVEL 0x38
58 
59 #define SID_USES_FILTER
60 //#define SID_DEBUG
61 
62 // switch between 'cycle' or 'sample' based envelope-generator counter
63 // (performance wise it does not seem to make much difference)
64 //#define SID_USES_SAMPLE_ENV_COUNTER
65 
66 
67 typedef enum {
68  Attack = 0,
69  Decay = 1,
70  Sustain = 2,
71  Release = 3,
73 
74 
75 #define NUMBER_OF_SID_REGISTERS_FOR_SNAPSHOT 0x20
76 
77 
78 struct SidEmulation {
81  struct SidRegisters {
82  struct SidVoice {
83  unsigned short freq;
84  unsigned short pulse;
85  unsigned char wave;
86  unsigned char ad;
87  unsigned char sr;
88  } v[3];
89  unsigned char ffreqlo;
90  unsigned char ffreqhi;
91  unsigned char res_ftv;
92  unsigned char ftp_vol;
93  } sid;
94  struct SidOsc { // internal oscillator def
95  unsigned long freq;
96  unsigned long pulse;
97  unsigned char wave;
98  unsigned char filter;
99  unsigned long attack;
100  unsigned long decay;
101  unsigned long sustain;
102  unsigned long release;
103  unsigned long counter;
104  // updated envelope generation based on reSID
105  unsigned char envelopeOutput;
106  signed int currentLFSR; // sim counter
107  unsigned char zero_lock;
108  unsigned char exponential_counter;
109  unsigned char envphase;
110  unsigned long noisepos;
111  unsigned long noiseval;
112  unsigned char noiseout;
113  } osc[3];
114  struct SidFilter { // internal filter def
115  int freq;
116  unsigned char l_ena;
117  unsigned char b_ena;
118  unsigned char h_ena;
119  unsigned char v3ena;
120  int vol;
121  int rez;
122  int h;
123  int b;
124  int l;
125  } filter;
126  unsigned int sMuteVoice[3];
127  unsigned long sCycles; // counter keeps track of burned cpu cycles
128  unsigned long sAdsrBugTriggerTime; // detection of ADSR-bug conditions
129  unsigned long sAdsrBugFrameCount;
132  // 0x38: supposedly DC level for MOS6581 (whereas it would be 0x80 for the "crappy new chip")
133  unsigned level_DC;
134 #ifdef SID_DEBUG
135  unsigned char voiceEnableMask; // for debugging: allows to mute certain voices..
136 #endif
137  int limit_LFSR; // the original cycle counter would be 15-bit (but we are counting samples & may rescale the counter accordingly)
140  unsigned long mixing_frequency;
141  unsigned long freqmul;
142  int filtmul;
143  unsigned long cyclesPerSec;
144  unsigned long sLastFrameCount;
145  unsigned char bval;
146  unsigned short wval;
147  unsigned long sLastPolledOsc;
148  SDL_SpinLock spinlock;
149 };
150 
151 
152 extern void sid_write_reg ( struct SidEmulation *sidemu, int reg, unsigned char val );
153 extern void sid_init ( struct SidEmulation *sidemu, unsigned long cyclesPerSec, unsigned long mixfrq );
154 extern void sid_render ( struct SidEmulation *sidemu, short *buffer, unsigned long len, int step );
155 
156 #ifdef XEMU_SNAPSHOT_SUPPORT
157 #include "xemu/emutools_basicdefs.h"
158 #include "xemu/emutools_snapshot.h"
159 extern int sid_snapshot_load_state ( const struct xemu_snapshot_definition_st *def , struct xemu_snapshot_block_st *block );
160 extern int sid_snapshot_save_state ( const struct xemu_snapshot_definition_st *def );
161 #endif
162 
163 #endif
SidEmulation::sMuteVoice
unsigned int sMuteVoice[3]
Definition: sid.h:126
SidEmulation::envelope_counter_period
int envelope_counter_period[16]
Definition: sid.h:138
Release
@ Release
Definition: sid.h:71
SidEmulation::SidRegisters::SidVoice::ad
unsigned char ad
Definition: sid.h:86
SidEmulation::SidOsc::currentLFSR
signed int currentLFSR
Definition: sid.h:106
SidEmulation::level_DC
unsigned level_DC
Definition: sid.h:133
SidEmulation::SidOsc::noiseval
unsigned long noiseval
Definition: sid.h:111
SidEmulation::sAdsrBugTriggerTime
unsigned long sAdsrBugTriggerTime
Definition: sid.h:128
NUMBER_OF_SID_REGISTERS_FOR_SNAPSHOT
#define NUMBER_OF_SID_REGISTERS_FOR_SNAPSHOT
Definition: sid.h:75
SidEmulation::SidOsc::sustain
unsigned long sustain
Definition: sid.h:101
SidEmulation::cycleOverflow
float cycleOverflow
Definition: sid.h:131
SidEmulation::SidRegisters::SidVoice::wave
unsigned char wave
Definition: sid.h:85
SidEmulation::SidOsc::decay
unsigned long decay
Definition: sid.h:100
SidEmulation::SidFilter::h_ena
unsigned char h_ena
Definition: sid.h:118
SidEmulation::SidRegisters::ffreqlo
unsigned char ffreqlo
Definition: sid.h:89
SidEmulation::SidOsc::freq
unsigned long freq
Definition: sid.h:95
EnvelopePhase
EnvelopePhase
Definition: sid.h:67
SidEmulation::SidRegisters::SidVoice::sr
unsigned char sr
Definition: sid.h:87
SidEmulation::SidFilter::l_ena
unsigned char l_ena
Definition: sid.h:116
SidEmulation::SidOsc::counter
unsigned long counter
Definition: sid.h:103
SidEmulation::SidOsc::pulse
unsigned long pulse
Definition: sid.h:96
SidEmulation::SidOsc::zero_lock
unsigned char zero_lock
Definition: sid.h:107
sid_init
void sid_init(struct SidEmulation *sidemu, unsigned long cyclesPerSec, unsigned long mixfrq)
Definition: sid.c:649
sid_write_reg
void sid_write_reg(struct SidEmulation *sidemu, int reg, unsigned char val)
Definition: sid.c:513
block
Uint32 block
Definition: fat32.c:156
SidEmulation::SidRegisters::SidVoice::freq
unsigned short freq
Definition: sid.h:83
SidEmulation::SidRegisters::res_ftv
unsigned char res_ftv
Definition: sid.h:91
SidEmulation::SidRegisters::ffreqhi
unsigned char ffreqhi
Definition: sid.h:90
emutools_basicdefs.h
SidEmulation::spinlock
SDL_SpinLock spinlock
Definition: sid.h:148
SidEmulation::SidOsc::envphase
unsigned char envphase
Definition: sid.h:109
SidEmulation::SidFilter::vol
int vol
Definition: sid.h:120
SidEmulation::cyclesPerSec
unsigned long cyclesPerSec
Definition: sid.h:143
SidEmulation::SidRegisters::v
struct SidEmulation::SidRegisters::SidVoice v[3]
SidEmulation::SidRegisters::SidVoice::pulse
unsigned short pulse
Definition: sid.h:84
SidEmulation::SidRegisters::SidVoice
Definition: sid.h:82
SidEmulation::SidFilter::b
int b
Definition: sid.h:123
SidEmulation::SidFilter::freq
int freq
Definition: sid.h:115
SidEmulation::writtenRegisterValues
unsigned char writtenRegisterValues[NUMBER_OF_SID_REGISTERS_FOR_SNAPSHOT]
Definition: sid.h:80
SidEmulation::SidFilter::v3ena
unsigned char v3ena
Definition: sid.h:119
SidEmulation::SidOsc::attack
unsigned long attack
Definition: sid.h:99
SidEmulation::bval
unsigned char bval
Definition: sid.h:145
SidEmulation::SidOsc::release
unsigned long release
Definition: sid.h:102
SidEmulation::wval
unsigned short wval
Definition: sid.h:146
SidEmulation::SidOsc::exponential_counter
unsigned char exponential_counter
Definition: sid.h:108
SidEmulation::filtmul
int filtmul
Definition: sid.h:142
SidEmulation::SidOsc::noisepos
unsigned long noisepos
Definition: sid.h:110
Sustain
@ Sustain
Definition: sid.h:70
SidEmulation::SidOsc::filter
unsigned char filter
Definition: sid.h:98
SidEmulation::filter
struct SidEmulation::SidFilter filter
SidEmulation::cyclesPerSample
float cyclesPerSample
Definition: sid.h:130
step
int step
Definition: dma65.c:84
SidEmulation::limit_LFSR
int limit_LFSR
Definition: sid.h:137
emutools_snapshot.h
SidEmulation::SidOsc::envelopeOutput
unsigned char envelopeOutput
Definition: sid.h:105
SidEmulation::envelope_counter_period_clck
int envelope_counter_period_clck[16]
Definition: sid.h:139
SidEmulation::sLastPolledOsc
unsigned long sLastPolledOsc
Definition: sid.h:147
Decay
@ Decay
Definition: sid.h:69
SidEmulation::SidOsc
Definition: sid.h:94
SidEmulation::sid
struct SidEmulation::SidRegisters sid
SidEmulation::SidOsc::noiseout
unsigned char noiseout
Definition: sid.h:112
SidEmulation::SidFilter::l
int l
Definition: sid.h:124
SidEmulation::SidFilter
Definition: sid.h:114
Attack
@ Attack
Definition: sid.h:68
SidEmulation::SidFilter::rez
int rez
Definition: sid.h:121
SidEmulation::SidRegisters
Definition: sid.h:81
SidEmulation::sCycles
unsigned long sCycles
Definition: sid.h:127
SidEmulation::mixing_frequency
unsigned long mixing_frequency
Definition: sid.h:140
SidEmulation::SidRegisters::ftp_vol
unsigned char ftp_vol
Definition: sid.h:92
SidEmulation::SidFilter::b_ena
unsigned char b_ena
Definition: sid.h:117
SidEmulation::sFrameCount
int sFrameCount
Definition: sid.h:79
SidEmulation::osc
struct SidEmulation::SidOsc osc[3]
SidEmulation::SidOsc::wave
unsigned char wave
Definition: sid.h:97
SidEmulation::sLastFrameCount
unsigned long sLastFrameCount
Definition: sid.h:144
SidEmulation::freqmul
unsigned long freqmul
Definition: sid.h:141
sid_render
void sid_render(struct SidEmulation *sidemu, short *buffer, unsigned long len, int step)
Definition: sid.c:256
SidEmulation
Definition: sid.h:78
SidEmulation::SidFilter::h
int h
Definition: sid.h:122
SidEmulation::sAdsrBugFrameCount
unsigned long sAdsrBugFrameCount
Definition: sid.h:129