summaryrefslogtreecommitdiffstats
path: root/lib/rbcodec/codecs/cRSID/C64/libcRSIDc64.h
blob: 5100680768c789570bb579acf84c6b425b0e74ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// cRSID lightweight RealSID (integer-only) library-header (with API-calls) by Hermit (Mihaly Horvath)

#ifndef LIBCRSIDC64_HEADER
#define LIBCRSIDC64_HEADER //used  to prevent double inclusion of this header-file

typedef struct cRSID_CPUinstance cRSID_CPUinstance;
typedef struct cRSID_SIDinstance cRSID_SIDinstance;
typedef struct cRSID_CIAinstance cRSID_CIAinstance;
typedef struct cRSID_VICinstance cRSID_VICinstance;


//Internal functions

// C64/C64.c
cRSID_C64instance*  cRSID_createC64     (cRSID_C64instance* C64, unsigned short samplerate);
void                cRSID_setC64        (cRSID_C64instance* C64); //configure hardware (SIDs) for SID-tune
void                cRSID_initC64       (cRSID_C64instance* C64); //hard-reset
int                 cRSID_emulateC64    (cRSID_C64instance* C64);
static inline short cRSID_playPSIDdigi  (cRSID_C64instance* C64);
// C64/MEM.c
static inline unsigned char* cRSID_getMemReadPtr     (register unsigned short address); //for global cSID_C64 fast-access
static inline unsigned char* cRSID_getMemReadPtrC64  (cRSID_C64instance* C64, register unsigned short address); //maybe slower
static inline unsigned char* cRSID_getMemWritePtr    (register unsigned short address); //for global cSID_C64 fast-access
static inline unsigned char* cRSID_getMemWritePtrC64 (cRSID_C64instance* C64, register unsigned short address); //maybe slower
static inline unsigned char  cRSID_readMem     (register unsigned short address); //for global cSID_C64 fast-access
static inline unsigned char  cRSID_readMemC64  (cRSID_C64instance* C64, register unsigned short address); //maybe slower
static inline void           cRSID_writeMem    (register unsigned short address, register unsigned char data); //for global cSID_C64 fast-access
static inline void           cRSID_writeMemC64 (cRSID_C64instance* C64, register unsigned short address, register unsigned char data); //maybe slower
void                         cRSID_setROMcontent (cRSID_C64instance* C64); //KERNAL, BASIC
void                         cRSID_initMem       (cRSID_C64instance* C64);
// C64/CPU.c
void               cRSID_initCPU       (cRSID_CPUinstance* CPU, unsigned short mempos);
unsigned char      cRSID_emulateCPU    (void); //direct instances inside for hopefully faster operation
static inline char cRSID_handleCPUinterrupts (cRSID_CPUinstance* CPU);
// C64/SID.c
void               cRSID_createSIDchip (cRSID_C64instance* C64, cRSID_SIDinstance* SID, unsigned short model, unsigned short baseaddress);
void               cRSID_initSIDchip   (cRSID_SIDinstance* SID);
void               cRSID_emulateADSRs  (cRSID_SIDinstance *SID, char cycles);
int                cRSID_emulateWaves  (cRSID_SIDinstance* SID);
// C64/CIA.c
void               cRSID_createCIAchip (cRSID_C64instance* C64, cRSID_CIAinstance* CIA, unsigned short baseaddress);
void               cRSID_initCIAchip   (cRSID_CIAinstance* CIA);
static inline char cRSID_emulateCIA    (cRSID_CIAinstance* CIA, char cycles);
static inline void cRSID_writeCIAIRQmask   (cRSID_CIAinstance* CIA, unsigned char value);
static inline void cRSID_acknowledgeCIAIRQ (cRSID_CIAinstance* CIA);
// C64/VIC.c
void               cRSID_createVICchip (cRSID_C64instance* C64, cRSID_VICinstance* VIC, unsigned short baseaddress);
void               cRSID_initVICchip   (cRSID_VICinstance* VIC);
static inline char cRSID_emulateVIC    (cRSID_VICinstance* VIC, char cycles);
static inline void cRSID_acknowledgeVICrasterIRQ (cRSID_VICinstance* VIC);

// host/file.c
#ifdef CRSID_PLATFORM_PC
int                cRSID_loadSIDfile   (unsigned char* SIDfileData, char* filename, int maxlen); //load SID-file to a memory location (and return size)
#endif
// host/audio.c
#ifdef CRSID_PLATFORM_PC
void*              cRSID_initSound     (cRSID_C64instance* C64, unsigned short samplerate, unsigned short buflen);
void               cRSID_startSound    (void);
void               cRSID_stopSound     (void);
void               cRSID_closeSound    (void);
void               cRSID_generateSound (cRSID_C64instance* C64, unsigned char* buf, unsigned short len);
#endif


struct cRSID_CPUinstance {
 cRSID_C64instance* C64; //reference to the containing C64
 unsigned int       PC;
 short int          A, SP;
 unsigned char      X, Y, ST;  //STATUS-flags: N V - B D I Z C
 unsigned char      PrevNMI; //used for NMI leading edge detection
};


struct cRSID_SIDinstance {
 //SID-chip data:
 cRSID_C64instance* C64;           //reference to the containing C64
 unsigned short     ChipModel;     //values: 8580 / 6581
 unsigned short     BaseAddress;   //SID-baseaddress location in C64-memory (IO)
 unsigned char*     BasePtr;       //SID-baseaddress location in host's memory
 //ADSR-related:
 unsigned char      ADSRstate[15];
 unsigned short     RateCounter[15];
 unsigned char      EnvelopeCounter[15];
 unsigned char      ExponentCounter[15];
 //Wave-related:
 int                PhaseAccu[15];       //28bit precision instead of 24bit
 int                PrevPhaseAccu[15];   //(integerized ClockRatio fractionals, WebSID has similar solution)
 unsigned char      SyncSourceMSBrise;
 unsigned int       RingSourceMSB;
 unsigned int       NoiseLFSR[15];
 unsigned int       PrevWavGenOut[15];
 unsigned char      PrevWavData[15];
 //Filter-related:
 int                PrevLowPass;
 int                PrevBandPass;
 //Output-stage:
 signed int         PrevVolume; //lowpass-filtered version of Volume-band register
};


struct cRSID_CIAinstance {
 cRSID_C64instance* C64;         //reference to the containing C64
 char               ChipModel;   //old or new CIA? (have 1 cycle difference in cases)
 unsigned short     BaseAddress; //CIA-baseaddress location in C64-memory (IO)
 unsigned char*     BasePtrWR;   //CIA-baseaddress location in host's memory for writing
 unsigned char*     BasePtrRD;   //CIA-baseaddress location in host's memory for reading
};


struct cRSID_VICinstance {
 cRSID_C64instance* C64;         //reference to the containing C64
 char               ChipModel;   //(timing differences between models?)
 unsigned short     BaseAddress; //VIC-baseaddress location in C64-memory (IO)
 unsigned char*     BasePtrWR;   //VIC-baseaddress location in host's memory for writing
 unsigned char*     BasePtrRD;   //VIC-baseaddress location in host's memory for reading
 unsigned short     RasterLines;
 unsigned char      RasterRowCycles;
 unsigned char      RowCycleCnt;
};


struct cRSID_C64instance {
 //platform-related:
 unsigned short    SampleRate;
 //C64-machine related:
 unsigned char     VideoStandard; //0:NTSC, 1:PAL (based on the SID-header field)
 unsigned int      CPUfrequency;
 unsigned short    SampleClockRatio; //ratio of CPU-clock and samplerate
 //SID-file related:
 union {
  cRSID_SIDheader*  SIDheader;
  char*             SIDfileData;
 };
 unsigned short    Attenuation;
 char              RealSIDmode;
 char              PSIDdigiMode;
 unsigned char     SubTune;
 unsigned short    LoadAddress;
 unsigned short    InitAddress;
 unsigned short    PlayAddress;
 unsigned short    EndAddress;
 char              TimerSource; //for current subtune, 0:VIC, 1:CIA (as in SID-header)
 //PSID-playback related:
 //char              CIAisSet; //for dynamic CIA setting from player-routine (RealSID substitution)
 int               FrameCycles;
 int               FrameCycleCnt; //this is a substitution in PSID-mode for CIA/VIC counters
 short             PrevRasterLine;
 short             SampleCycleCnt;
 short             TenthSecondCnt;
 char              Finished;
 char              Returned;
 unsigned char     IRQ; //collected IRQ line from devices
 unsigned char     NMI; //collected NMI line from devices

 //Hardware-elements:
 cRSID_CPUinstance CPU;
 cRSID_SIDinstance SID[CRSID_SIDCOUNT_MAX+1];
 cRSID_CIAinstance CIA[CRSID_CIACOUNT+1];
 cRSID_VICinstance VIC;
 //Overlapping system memories, which one is read/written in an address region depends on CPU-port bankselect-bits)
 //Address $00 and $01 - data-direction and data-register of port built into CPU (used as bank-selection) (overriding RAM on C64)
 unsigned char RAMbank[0x10100];  //$0000..$FFFF RAM (and RAM under IO/ROM/CPUport)
 unsigned char IObankWR[0x10100]; //$D000..$DFFF IO-RAM (registers) to write (VIC/SID/CIA/ColorRAM/IOexpansion)
 unsigned char IObankRD[0x10100]; //$D000..$DFFF IO-RAM (registers) to read from (VIC/SID/CIA/ColorRAM/IOexpansion)
 unsigned char ROMbanks[0x10100]; //$1000..$1FFF/$9000..$9FFF (CHARGEN), $A000..$BFFF (BASIC), $E000..$FFFF (KERNAL)
};

cRSID_C64instance cRSID_C64; //the only global object (for faster & simpler access than with struct-pointers, in some places)


#endif //LIBCRSIDC64_HEADER