mirror of https://github.com/bsnes-emu/bsnes.git
Serial API
This commit is contained in:
parent
15f6412581
commit
22c34e1095
29
Core/gb.c
29
Core/gb.c
|
@ -503,6 +503,35 @@ void GB_set_rumble_callback(GB_gameboy_t *gb, GB_rumble_callback_t callback)
|
||||||
gb->rumble_callback = callback;
|
gb->rumble_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GB_set_serial_transfer_start_callback(GB_gameboy_t *gb, GB_serial_transfer_start_callback_t callback)
|
||||||
|
{
|
||||||
|
gb->serial_transfer_start_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GB_set_serial_transfer_end_callback(GB_gameboy_t *gb, GB_serial_transfer_end_callback_t callback)
|
||||||
|
{
|
||||||
|
gb->serial_transfer_end_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t GB_serial_get_data(GB_gameboy_t *gb)
|
||||||
|
{
|
||||||
|
if (gb->io_registers[GB_IO_SC] & 1) {
|
||||||
|
/* Internal Clock */
|
||||||
|
GB_log(gb, "Serial read request while using internal clock. \n");
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
return gb->io_registers[GB_IO_SB];
|
||||||
|
}
|
||||||
|
void GB_serial_set_data(GB_gameboy_t *gb, uint8_t data)
|
||||||
|
{
|
||||||
|
if (gb->io_registers[GB_IO_SC] & 1) {
|
||||||
|
/* Internal Clock */
|
||||||
|
GB_log(gb, "Serial write request while using internal clock. \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gb->io_registers[GB_IO_SB] = data;
|
||||||
|
}
|
||||||
|
|
||||||
void GB_set_sample_rate(GB_gameboy_t *gb, unsigned int sample_rate)
|
void GB_set_sample_rate(GB_gameboy_t *gb, unsigned int sample_rate)
|
||||||
{
|
{
|
||||||
if (gb->audio_buffer) {
|
if (gb->audio_buffer) {
|
||||||
|
|
15
Core/gb.h
15
Core/gb.h
|
@ -162,6 +162,9 @@ typedef void (*GB_infrared_callback_t)(GB_gameboy_t *gb, bool on, long cycles_si
|
||||||
typedef uint8_t (*GB_camera_get_pixel_callback_t)(GB_gameboy_t *gb, uint8_t x, uint8_t y);
|
typedef uint8_t (*GB_camera_get_pixel_callback_t)(GB_gameboy_t *gb, uint8_t x, uint8_t y);
|
||||||
typedef void (*GB_camera_update_request_callback_t)(GB_gameboy_t *gb);
|
typedef void (*GB_camera_update_request_callback_t)(GB_gameboy_t *gb);
|
||||||
typedef void (*GB_rumble_callback_t)(GB_gameboy_t *gb, bool rumble_on);
|
typedef void (*GB_rumble_callback_t)(GB_gameboy_t *gb, bool rumble_on);
|
||||||
|
typedef void (*GB_serial_transfer_start_callback_t)(GB_gameboy_t *gb, uint8_t byte_to_send);
|
||||||
|
typedef uint8_t (*GB_serial_transfer_end_callback_t)(GB_gameboy_t *gb);
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
enum {
|
enum {
|
||||||
|
@ -418,7 +421,8 @@ typedef struct GB_gameboy_s {
|
||||||
GB_camera_get_pixel_callback_t camera_get_pixel_callback;
|
GB_camera_get_pixel_callback_t camera_get_pixel_callback;
|
||||||
GB_camera_update_request_callback_t camera_update_request_callback;
|
GB_camera_update_request_callback_t camera_update_request_callback;
|
||||||
GB_rumble_callback_t rumble_callback;
|
GB_rumble_callback_t rumble_callback;
|
||||||
|
GB_serial_transfer_start_callback_t serial_transfer_start_callback;
|
||||||
|
GB_serial_transfer_end_callback_t serial_transfer_end_callback;
|
||||||
/* IR */
|
/* IR */
|
||||||
long cycles_since_ir_change;
|
long cycles_since_ir_change;
|
||||||
long cycles_since_input_ir_change;
|
long cycles_since_input_ir_change;
|
||||||
|
@ -497,4 +501,13 @@ void GB_set_infrared_callback(GB_gameboy_t *gb, GB_infrared_callback_t callback)
|
||||||
void GB_set_infrared_input(GB_gameboy_t *gb, bool state);
|
void GB_set_infrared_input(GB_gameboy_t *gb, bool state);
|
||||||
void GB_queue_infrared_input(GB_gameboy_t *gb, bool state, long cycles_after_previous_change);
|
void GB_queue_infrared_input(GB_gameboy_t *gb, bool state, long cycles_after_previous_change);
|
||||||
void GB_set_rumble_callback(GB_gameboy_t *gb, GB_rumble_callback_t callback);
|
void GB_set_rumble_callback(GB_gameboy_t *gb, GB_rumble_callback_t callback);
|
||||||
|
|
||||||
|
/* These APIs are used when using internal clock */
|
||||||
|
void GB_set_serial_transfer_start_callback(GB_gameboy_t *gb, GB_serial_transfer_start_callback_t callback);
|
||||||
|
void GB_set_serial_transfer_end_callback(GB_gameboy_t *gb, GB_serial_transfer_end_callback_t callback);
|
||||||
|
|
||||||
|
/* These APIs are used when using external clock */
|
||||||
|
uint8_t GB_serial_get_data(GB_gameboy_t *gb);
|
||||||
|
void GB_serial_set_data(GB_gameboy_t *gb, uint8_t data);
|
||||||
|
|
||||||
#endif /* GB_h */
|
#endif /* GB_h */
|
||||||
|
|
|
@ -576,6 +576,9 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
||||||
gb->io_registers[GB_IO_SC] = value | (~0x83);
|
gb->io_registers[GB_IO_SC] = value | (~0x83);
|
||||||
if ((value & 0x80) && (value & 0x1) ) {
|
if ((value & 0x80) && (value & 0x1) ) {
|
||||||
gb->serial_cycles = gb->cgb_mode && (value & 2)? 128 : 4096;
|
gb->serial_cycles = gb->cgb_mode && (value & 2)? 128 : 4096;
|
||||||
|
if (gb->serial_transfer_start_callback) {
|
||||||
|
gb->serial_transfer_start_callback(gb, gb->io_registers[GB_IO_SB]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gb->serial_cycles = 0;
|
gb->serial_cycles = 0;
|
||||||
|
|
|
@ -45,7 +45,14 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
||||||
if (gb->serial_cycles <= cycles) {
|
if (gb->serial_cycles <= cycles) {
|
||||||
gb->serial_cycles = 0;
|
gb->serial_cycles = 0;
|
||||||
gb->io_registers[GB_IO_SC] &= ~0x80;
|
gb->io_registers[GB_IO_SC] &= ~0x80;
|
||||||
gb->io_registers[GB_IO_SB] = 0xFF;
|
/* TODO: Does SB "update" bit by bit? */
|
||||||
|
if (gb->serial_transfer_end_callback) {
|
||||||
|
gb->io_registers[GB_IO_SB] = gb->serial_transfer_end_callback(gb);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gb->io_registers[GB_IO_SB] = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
gb->io_registers[GB_IO_IF] |= 8;
|
gb->io_registers[GB_IO_IF] |= 8;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in New Issue