2024-10-20 01:35:56 +00:00
|
|
|
/* This file is included into vb.c and cannot be compiled on its own. */
|
|
|
|
#ifdef VBAPI
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************************** Library Functions *****************************/
|
|
|
|
|
|
|
|
/* Process component */
|
2024-10-20 23:52:19 +00:00
|
|
|
static void padEmulate(VB *sim, uint32_t clocks) {
|
2024-10-20 01:35:56 +00:00
|
|
|
|
|
|
|
/* No hardware read in progress */
|
|
|
|
if (sim->pad.si_stat == 0)
|
2024-10-20 23:52:19 +00:00
|
|
|
return;
|
2024-10-20 01:35:56 +00:00
|
|
|
|
|
|
|
/* Hardware read completes after time to process */
|
|
|
|
if (sim->pad.si_stat > clocks) {
|
|
|
|
sim->pad.si_stat -= clocks;
|
2024-10-20 23:52:19 +00:00
|
|
|
return;
|
2024-10-20 01:35:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Complete hardware read */
|
|
|
|
sim->pad.si_stat = 0;
|
|
|
|
sim->pad.sdlr = sim->pad.keys;
|
|
|
|
sim->pad.sdhr = sim->pad.keys >> 8;
|
|
|
|
|
|
|
|
/* Raise game pad interrupt */
|
|
|
|
if (
|
|
|
|
!sim->pad.k_int_inh &&
|
|
|
|
(sim->pad.keys & 0xFFF0) != 0 &&
|
|
|
|
(sim->pad.keys & 0x000E) == 0
|
|
|
|
) sim->cpu.irq |= 0x0001;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Read a value from SCR */
|
|
|
|
static int32_t padReadControl(VB *sim) {
|
|
|
|
return 0x4C |
|
|
|
|
sim->pad.k_int_inh << 7 |
|
|
|
|
sim->pad.para_si << 5 |
|
|
|
|
sim->pad.soft_ck << 4 |
|
|
|
|
!!sim->pad.si_stat << 1 |
|
|
|
|
sim->pad.s_abt_dis
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Simulate a hardware reset */
|
|
|
|
static void padReset(VB *sim) {
|
|
|
|
|
|
|
|
/* Normal */
|
|
|
|
sim->pad.k_int_inh = 0;
|
|
|
|
sim->pad.para_si = 0;
|
|
|
|
sim->pad.s_abt_dis = 0;
|
|
|
|
sim->pad.sdhr = 0x00;
|
|
|
|
sim->pad.sdlr = 0x00;
|
|
|
|
sim->pad.si_stat = 0;
|
|
|
|
sim->pad.soft_ck = 0;
|
|
|
|
|
|
|
|
/* Other */
|
|
|
|
sim->pad.step = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write a value to SCR */
|
|
|
|
static void padWriteControl(VB *sim, uint8_t value) {
|
|
|
|
|
|
|
|
/* Acknowledge and disable interrupt */
|
|
|
|
sim->pad.k_int_inh = value >> 7 & 1;
|
|
|
|
if (sim->pad.k_int_inh)
|
|
|
|
sim->cpu.irq &= ~0x0001;
|
|
|
|
|
|
|
|
/* Enable or disable hardware reads */
|
|
|
|
sim->pad.s_abt_dis = value & 1;
|
|
|
|
if (sim->pad.s_abt_dis)
|
|
|
|
sim->pad.si_stat = 0; /* Abort hardware read */
|
|
|
|
|
|
|
|
/* Initiate a hardware read */
|
|
|
|
if (
|
|
|
|
(value & 0x04) && /* HW-SI */
|
|
|
|
sim->pad.si_stat == 0 && /* No hardware read underway */
|
|
|
|
!sim->pad.s_abt_dis /* Hardware reads enabled */
|
|
|
|
) {
|
|
|
|
sim->pad.si_stat = 10240; /* 512us */
|
|
|
|
sim->pad.step = 0; /* Abort software read */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reset the read operation */
|
|
|
|
sim->pad.para_si = value >> 5 & 1;
|
|
|
|
if (
|
|
|
|
sim->pad.para_si &&
|
|
|
|
sim->pad.si_stat == 0 /* No hardware read underway */
|
|
|
|
) sim->pad.step = 32;
|
|
|
|
|
|
|
|
/* Signal a bit for a software read */
|
|
|
|
sim->pad.soft_ck = value >> 4 & 1;
|
|
|
|
if (
|
|
|
|
sim->pad.step != 0 && /* Software read is underway */
|
|
|
|
!sim->pad.para_si && /* Not resetting software read */
|
|
|
|
((sim->pad.soft_ck ^ sim->pad.step) & 1) == 1 /* Advance */
|
|
|
|
) {
|
|
|
|
sim->pad.step--;
|
|
|
|
if (sim->pad.step == 0) {
|
|
|
|
sim->pad.sdlr = sim->pad.keys;
|
|
|
|
sim->pad.sdhr = sim->pad.keys >> 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Determine how many clocks are guaranteed to process */
|
|
|
|
static uint32_t padUntil(VB *sim, uint32_t clocks) {
|
|
|
|
return sim->pad.si_stat != 0 && sim->pad.si_stat < clocks ?
|
|
|
|
sim->pad.si_stat : clocks;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* VBAPI */
|