libmsx
C library for MSX
Loading...
Searching...
No Matches

#include <scc_buf.h> Buffered access to SCC/SCC+ registers. More...

+ Collaboration diagram for SCC/SCC+ Buffer:

Data Structures

struct  SCC_buffer
 
struct  SCC_wave_buffer
 

Functions

void SCC_init (void)
 MSX Initialize scc_buffer and internal waveform buffer.
 
void SCC_set_waveform (uint8_t ch, const int8_t waveform[32])
 MSX Set waveform to the internal waveform buffer, for the specified channel.
 
void SCC_stop (struct SCC *scc)
 MSX Stop (Pause) playing sound on SCC/SCC+.
 
void SCC_play (struct SCC *scc)
 MSX Play sound on SCC/SCC+.
 

Variables

struct SCC_wave_buffer scc_wave_buffer
 MSX Buffer for SCC/SCC+ waveform registers.
 
struct SCC_buffer scc_buffer
 MSX Buffer for SCC/SCC+ registers (except for waveform registers).
 

Detailed Description

#include <scc_buf.h> Buffered access to SCC/SCC+ registers.

Provides simple APIs for sound driver developpers.

Example
The following code shows a sound driver/replayer template for the Konami SCC/SCC+ sound chip.

// -*- coding: utf-8-unix -*-
/*
* Copyright (c) 2021-2024 Daishi Mori (mori0091)
*
* This software is released under the MIT License.\n
* See https://github.com/mori0091/libmsx/blob/main/LICENSE
*
* GitHub libmsx project\n
* https://github.com/mori0091/libmsx
*/
#include <msx.h>
#include <scc_buf.h>
#include <scc_wav.h>
static struct SCC scc;
static bool paused;
// Initialize the replayer.
void init(void) {
if (SCC_find(&scc)) {
// Set to SCC+ mode if available. (optional)
// The mode will be applied to the sound chip when SCC_enable() is called.
SCC_set_mode(&scc, 2);
// Enable SCC/SCC+.
// This must be called at least once.
// It must also be called when the mode is changed by SCC_set_mode().
SCC_enable(&scc);
// Initialize `scc_buffer` and internal waveform buffer.
// Initialize waveform buffers (if needed).
SCC_set_waveform(2, SCC_WAVEFORM_SQUARE); // 1/2 pulse / square
SCC_set_waveform(4, SCC_WAVEFORM_TRIANGLE); // (available for SCC+ mode only)
}
}
// Main routine of the replayer.
// \note This shall be called every VSYNC timing from interrupt handler.
void play(void) {
if (!scc.slot) return;
if (paused) return;
// Apply buffered values to the SCC/SCC+ registers.
SCC_play(&scc);
// Decode one frame of music data and set them to buffers.
// (Rewrite this block for developping yourown sound driver / replayer)
{
// Update buffered values for each channels (if needed).
for (uint8_t ch = 0; ch < 5; ch++) {
// Update waveform buffer
// SCC_set_waveform(ch, SCC_WAVEFORM_TRIANGLE);
// Update frequency division ratio (i.e., period)
scc_buffer.fdr[ch] = 0x11d; // O4 G
// Update volume.
scc_buffer.volume[ch] = 2;
}
// Update buffered channel mask value (if needed).
scc_buffer.channel_mask = 0x1F; // enable all 5 channels
}
}
// Start / Resume the replayer.
void start(void) {
paused = false;
}
// Pause the replayer.
void pause(void) {
paused = true;
SCC_stop(&scc);
__asm__("ei");
}
// Return whether the replayer is paused or not.
bool is_paused(void) {
return paused;
}
// Stop the replayer.
void stop(void) {
pause();
// Re-initialize `scc_buffer` and internal waveform buffer.
// (if needed)
}
void main(void) {
// Initialize our replayer.
init();
// Set our replayer `play()` to VSYNC handler
// Start our replayer.
start();
uint8_t pressed = false;
for (;;) {
uint8_t joy = joypad_get_state(0);
uint8_t clicked = pressed & ~joy;
pressed = joy;
if (clicked & VK_FIRE_0) {
if (is_paused()) {
start();
}
else {
pause();
}
}
}
}
uint8_t joypad_get_state(uint8_t controller)
MSX Get the status of the joystick buttons and levers.
#define VK_FIRE_0
Bitmask for trigger button #1 or SPACE key.
Definition input.h:68
void await_vsync(void)
MSX Waits for next VSYNC interrupt.
void set_vsync_handler(void(*handler)(void))
MSX Register user defined VSYNC interrupt handler.
uint8_t channel_mask
Enable / Disable bit for each of the five channels.
Definition scc_buf.h:51
uint8_t volume[5]
Volume (0-15) for each of the five channels.
Definition scc_buf.h:49
uint16_t fdr[5]
Frequency division ratio for each of the five channels.
Definition scc_buf.h:47
void SCC_init(void)
MSX Initialize scc_buffer and internal waveform buffer.
void SCC_set_waveform(uint8_t ch, const int8_t waveform[32])
MSX Set waveform to the internal waveform buffer, for the specified channel.
void SCC_play(struct SCC *scc)
MSX Play sound on SCC/SCC+.
void SCC_stop(struct SCC *scc)
MSX Stop (Pause) playing sound on SCC/SCC+.
struct SCC_buffer scc_buffer
MSX Buffer for SCC/SCC+ registers (except for waveform registers).
void SCC_enable(const struct SCC *scc)
MSX Enable SCC/SCC+ sound chip.
void SCC_set_mode(struct SCC *scc, uint8_t mode)
MSX Set the SCC handle to SCC compatible mode or SCC+ mode.
uint8_t SCC_find(struct SCC *scc)
MSX Find SCC/SCC+ sound chip.
SCC Handle.
Definition scc.h:106
#define SCC_WAVEFORM_PULSE_1_8
Definition scc_wav.h:86
#define SCC_WAVEFORM_PULSE_1_4
Definition scc_wav.h:90
#define SCC_WAVEFORM_SQUARE
Definition scc_wav.h:94
const int8_t SCC_WAVEFORM_TRIANGLE[32]
Trianguler wave.
Using #include <msx.h> includes almost all C header files in libmsx, for ease to use.
Buffered access to SCC/SCC+ registers.
Predefined waveforms for SCC/SCC+.

Data Structure Documentation

◆ SCC_buffer

struct SCC_buffer

Definition at line 45 of file scc_buf.h.

Data Fields
uint16_t fdr[5] Frequency division ratio for each of the five channels.
uint8_t volume[5] Volume (0-15) for each of the five channels.
uint8_t channel_mask Enable / Disable bit for each of the five channels.

◆ SCC_wave_buffer

struct SCC_wave_buffer

Definition at line 54 of file scc_buf.h.

Data Fields
uint8_t updated Update-bit for each of five channels.
int8_t waveform[5][32] Waveform for each of five channels.

Function Documentation

◆ SCC_init()

void SCC_init ( void  )

MSX Initialize scc_buffer and internal waveform buffer.

This must be called at least once before SCC_stop() or SCC_play().

◆ SCC_set_waveform()

void SCC_set_waveform ( uint8_t  ch,
const int8_t  waveform[32] 
)

MSX Set waveform to the internal waveform buffer, for the specified channel.

Parameters
chchannel # 0..3 for SCC, 0..4 for SCC+.
waveformpointer to 32 bytes waveform pattern.
Note
The waveform is applied onto SCC/SCC+ when SCC_play() is called.
In case of SCC and SCC compatible mode of SCC+, waveform register of the 4th channel (ch = 3) and the 5th channel (ch = 4) are shared.

◆ SCC_stop()

void SCC_stop ( struct SCC scc)

MSX Stop (Pause) playing sound on SCC/SCC+.

This function sets all volume registers to 0.

Parameters
sccpointer to the SCC handle.
Postcondition
Interrupt is disabled.
See also
SCC_find()
SCC_set_mode()
SCC_get_mode()
Note
This function simply sets all channels' volume level to 0.

◆ SCC_play()

void SCC_play ( struct SCC scc)

MSX Play sound on SCC/SCC+.

This function applies the value of scc_buffer to SCC/SCC+. It also applies the value of the internal waveform buffer if it has been updated.

Parameters
sccpointer to the SCC handle.
Postcondition
Interrupt is disabled.
See also
SCC_find()
SCC_set_mode()
SCC_get_mode()

Variable Documentation

◆ scc_wave_buffer

struct SCC_wave_buffer scc_wave_buffer
extern

MSX Buffer for SCC/SCC+ waveform registers.

Note
Use SCC_set_waveform() for setting waveform buffers.

◆ scc_buffer

struct SCC_buffer scc_buffer
extern

MSX Buffer for SCC/SCC+ registers (except for waveform registers).

Note
Use SCC_set_waveform() for setting waveform buffers.