libsidplayfp  2.0.2
Classes | Macros | Typedefs | Functions | Variables
exSID.c File Reference
#include "exSID.h"
#include "exSID_defs.h"
#include "exSID_ftdiwrap.h"
#include <stdio.h>
#include <unistd.h>
#include <inttypes.h>
Include dependency graph for exSID.c:

Classes

struct  xSpriv_s
 

Macros

#define ARRAY_SIZE(x)   (sizeof(x) / sizeof(x[0]))
 

Typedefs

typedef int_fast32_t clkdrift_t
 

Functions

const char * exSID_error_str (void)
 
int exSID_init (void)
 
void exSID_exit (void)
 
void exSID_reset (uint_least8_t volume)
 
int exSID_clockselect (int clock)
 
int exSID_audio_op (int operation)
 
void exSID_chipselect (int chip)
 
int exSID_hwmodel (void)
 
uint16_t exSID_hwversion (void)
 
void exSID_delay (uint_fast32_t cycles)
 
void exSID_clkdwrite (uint_fast32_t cycles, uint_least8_t addr, uint8_t data)
 
uint8_t exSID_clkdread (uint_fast32_t cycles, uint_least8_t addr)
 

Variables

char xSerrstr []
 
struct {
   const char *   desc
 
   const int   pid
 
   const int   vid
 
   const struct xSpriv_s   xsp
 
xSsupported []
 
const struct xSpriv_s *restrict xSpriv
 

Detailed Description

exSID/exSID+ USB I/O library

Author
Thibaut VARENE
Date
2015-2018
Version
2.0

This driver will control the first exSID device available. All public API functions are only valid after a successful call to exSID_init(). To release the device and resources, exSID_exit() must be called.

Typedef Documentation

◆ clkdrift_t

typedef int_fast32_t clkdrift_t

cycles is uint_fast32_t. Technically, clkdrift should be int_fast64_t though overflow should not happen under normal conditions.

Function Documentation

◆ exSID_audio_op()

int exSID_audio_op ( int  operation)

exSID+ audio operations routine. Selects the audio mixing / muting option. Only implemented in exSID+ devices.

Warning
all these operations (excepting unmuting obviously) will mute the output by default.
Note
no accounting for SID cycles consumed.
Parameters
operationaudio operation value, see exSID.h.
Returns
execution status

◆ exSID_chipselect()

void exSID_chipselect ( int  chip)

SID chipselect routine. Selects which SID will play the tunes. If neither CHIP0 or CHIP1 is chosen, both SIDs will operate together. Accounts for elapsed cycles.

Parameters
chipSID selector value, see exSID.h.

◆ exSID_clkdread()

uint8_t exSID_clkdread ( uint_fast32_t  cycles,
uint_least8_t  addr 
)

BLOCKING Timed read routine, attempts cycle-accurate reads. The following description is based on exSID (standard). This function will be cycle-accurate provided that no two consecutive reads or writes are less than XS_CYCIO apart and leftover delay is <= max_adj SID clock cycles. Read result will only be available after a full XS_CYCIO, giving clkdread() the same run time as clkdwrite(). There's a 2-cycle negative adjustment in the code because that's the actual offset from the write calls ('/' denotes falling clock edge latch), which the following ASCII tries to illustrate:
Write looks like this in firmware:

...|_/_|...

...end of data byte read | cycle during which write is enacted / next cycle | etc...
Read looks like this in firmware:

...|_|_|_/_|_|...

...end of address byte read | 2 cycles for address processing | cycle during which SID is read / then half a cycle later the CYCCHR-long data TX starts, cycle completes | another cycle | etc...
This explains why reads happen a relative 2-cycle later than then should with respect to writes.

Note
The actual time the read will take to complete depends on the USB bus activity and settings. It should complete in XS_USBLAT ms, but not less, meaning that read operations are bound to introduce timing inaccuracy. As such, this function is only really provided as a proof of concept but SHOULD BETTER BE AVOIDED.
Parameters
cycleshow many SID clocks to wait before the actual data read.
addrtarget address.
Returns
data read from address.

◆ exSID_clkdwrite()

void exSID_clkdwrite ( uint_fast32_t  cycles,
uint_least8_t  addr,
uint8_t  data 
)

Timed write routine, attempts cycle-accurate writes. This function will be cycle-accurate provided that no two consecutive reads or writes are less than write_cycles apart and the leftover delay is <= max_adj SID clock cycles.

Parameters
cycleshow many SID clocks to wait before the actual data write.
addrtarget address.
datadata to write at that address.

◆ exSID_clockselect()

int exSID_clockselect ( int  clock)

exSID+ clock selection routine. Selects between PAL, NTSC and 1MHz clocks.

Note
upon clock change the hardware resync itself and resets the SIDs, which takes approximately 50us: this function waits for enough time before resuming execution via a call to usleep(); Output should be muted before execution
Parameters
clockclock selector value, see exSID.h.
Returns
execution status

◆ exSID_delay()

void exSID_delay ( uint_fast32_t  cycles)

Cycle accurate delay routine. Applies the most efficient strategy to delay for cycles SID clocks while leaving enough lead time for an I/O operation.

Parameters
cycleshow many SID clocks to loop for.

◆ exSID_error_str()

const char* exSID_error_str ( void  )

Returns a string describing the last recorded error.

Returns
error message (max 256 bytes long).

◆ exSID_exit()

void exSID_exit ( void  )

Device exit routine. Must be called to release the device. Resets the SIDs and clears RX/TX buffers, releases all resources allocated in exSID_init().

◆ exSID_hwmodel()

int exSID_hwmodel ( void  )

Device hardware model. Queries the driver for the hardware model currently identified.

Returns
hardware model as enumerated in exSID.h, negative value on error.

◆ exSID_hwversion()

uint16_t exSID_hwversion ( void  )

Hardware and firmware version of the device. Queries the device for the hardware revision and current firmware version and returns both in the form of a 16bit integer: MSB is an ASCII character representing the hardware revision (e.g. 0x42 = "B"), and LSB is a number representing the firmware version in decimal integer. Does NOT account for elapsed cycles.

Returns
version information as described above.

◆ exSID_init()

int exSID_init ( void  )

Device init routine. Must be called once before any operation is attempted on the device. Opens first available device, and sets various parameters: baudrate, parity, flow control and USB latency, and finally clears the RX and TX buffers.

Returns
0 on success, !0 otherwise.

◆ exSID_reset()

void exSID_reset ( uint_least8_t  volume)

SID reset routine. Performs a hardware reset on the SIDs.

Note
since the reset procedure in firmware will stall the device, reset forcefully waits for enough time before resuming execution via a call to usleep();
Parameters
volumevolume to set the SIDs to after reset.

Variable Documentation

◆ xSpriv

const struct xSpriv_s* restrict xSpriv

Global pointer used by all the hardware access routines

◆ xSsupported

const { ... } xSsupported[]

Array of supported devices