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

Buffered access to PSG registers. More...

+ Collaboration diagram for PSG Buffer:

Functions

void ay_3_8910_init (void)
 MSX Initialize ay_3_8910_buffer[].
 
void ay_3_8910_stop (void)
 MSX Stop (Pause) playing sound on PSG.
 
void ay_3_8910_play (void)
 MSX Write the buffer contents to PSG registers.
 

Variables

uint8_t ay_3_8910_buffer [14]
 Buffer for PSG (AY-3-8910) registers.
 

Detailed Description

Buffered access to PSG registers.

Example
The following code shows a sound driver/replayer template for the PSG.

// -*- 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 <ay_3_8910.h>
#define LO_BYTE(x) (uint8_t)((x) & 0xff)
#define HI_BYTE(x) (uint8_t)(((x) >> 8) & 0xff)
static bool paused;
// Initialize the replayer.
void init(void) {
}
// Main routine of the replayer.
// \note This shall be called every VSYNC timing from interrupt handler.
void play(void) {
if (paused) return;
// Apply buffered values to the PSG registers.
// 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 < 3; ch++) {
// Update frequency division ratio (i.e., period)
ay_3_8910_buffer[2*ch+0] = LO_BYTE(0x11d); // O4 G (lo-byte)
ay_3_8910_buffer[2*ch+1] = HI_BYTE(0x11d); // O4 G (hi-byte)
// Update volume.
ay_3_8910_buffer[ch+8] = 8;
}
// Update buffered mixer value (if needed).
ay_3_8910_buffer[7] = 0xb8; // enable TONE of all 3 channels
// ...and so on
}
}
// Start / Resume the replayer.
void start(void) {
paused = false;
}
// Pause the replayer.
void pause(void) {
paused = true;
__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 internal 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();
}
}
}
}
Buffer for PSG (AY-3-8910) registers.
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 ay_3_8910_buffer[14]
Buffer for PSG (AY-3-8910) registers.
void ay_3_8910_play(void)
MSX Write the buffer contents to PSG registers.
void ay_3_8910_stop(void)
MSX Stop (Pause) playing sound on PSG.
void ay_3_8910_init(void)
MSX Initialize ay_3_8910_buffer[].
Using #include <msx.h> includes almost all C header files in libmsx, for ease to use.

Function Documentation

◆ ay_3_8910_init()

void ay_3_8910_init ( void  )

MSX Initialize ay_3_8910_buffer[].

◆ ay_3_8910_stop()

void ay_3_8910_stop ( void  )

MSX Stop (Pause) playing sound on PSG.

This function sets all volume registers to 0.

Note
This function simply sets all channels' volume level to 0.

◆ ay_3_8910_play()

void ay_3_8910_play ( void  )

MSX Write the buffer contents to PSG registers.

Note
PSG R#13 register is overwritten only if ay_3_8910_buffer[13] had been updated, and then the ay_3_8910_buffer[13] is reinitialized.
Any other PSG registers (R#0..12) are always overwritten with corresponding buffer value.

Variable Documentation

◆ ay_3_8910_buffer

uint8_t ay_3_8910_buffer[14]
extern

Buffer for PSG (AY-3-8910) registers.