mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 23:37:46 -04:00
mcd, some improvements (dma timing, interrupt handling)
This commit is contained in:
parent
4447902711
commit
691abdfa0f
3 changed files with 22 additions and 19 deletions
|
@ -66,6 +66,7 @@
|
||||||
|
|
||||||
/* PicoDrive: doing DMA at once, not using callbacks */
|
/* PicoDrive: doing DMA at once, not using callbacks */
|
||||||
//#define DMA_BYTES_PER_LINE 512
|
//#define DMA_BYTES_PER_LINE 512
|
||||||
|
#define DMA_CYCLES_PER_BYTE 4 // or 6?
|
||||||
|
|
||||||
enum dma_type {
|
enum dma_type {
|
||||||
word_ram_0_dma_w = 1,
|
word_ram_0_dma_w = 1,
|
||||||
|
@ -354,7 +355,7 @@ void cdc_dma_update(void)
|
||||||
do_dma(cdc.dma_w, cdc.dbc + 1);
|
do_dma(cdc.dma_w, cdc.dbc + 1);
|
||||||
|
|
||||||
/* reset data byte counter (DBCH bits 4-7 should be set to 1) */
|
/* reset data byte counter (DBCH bits 4-7 should be set to 1) */
|
||||||
cdc.dbc = 0xf000;
|
cdc.dbc = 0xffff;
|
||||||
|
|
||||||
/* clear !DTEN and !DTBSY */
|
/* clear !DTEN and !DTBSY */
|
||||||
cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
|
cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
|
||||||
|
@ -405,6 +406,9 @@ int cdc_decoder_update(uint8 header[4])
|
||||||
/* set !VALST */
|
/* set !VALST */
|
||||||
cdc.stat[3] = 0x00;
|
cdc.stat[3] = 0x00;
|
||||||
|
|
||||||
|
/* set CRCOK bit */
|
||||||
|
cdc.stat[0] = BIT_DECEN;
|
||||||
|
|
||||||
/* pending decoder interrupt */
|
/* pending decoder interrupt */
|
||||||
cdc.ifstat &= ~BIT_DECI;
|
cdc.ifstat &= ~BIT_DECI;
|
||||||
|
|
||||||
|
@ -602,7 +606,7 @@ void cdc_reg_w(unsigned char data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cdc.dma_w)
|
if (cdc.dma_w)
|
||||||
pcd_event_schedule_s68k(PCD_EVENT_DMA, cdc.dbc / 2);
|
pcd_event_schedule_s68k(PCD_EVENT_DMA, cdc.dbc * DMA_CYCLES_PER_BYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pico_mcd->s68k_regs[0x04+1] = 0x07;
|
Pico_mcd->s68k_regs[0x04+1] = 0x07;
|
||||||
|
@ -643,11 +647,8 @@ void cdc_reg_w(unsigned char data)
|
||||||
|
|
||||||
case 0x0a: /* CTRL0 */
|
case 0x0a: /* CTRL0 */
|
||||||
{
|
{
|
||||||
/* set CRCOK bit only if decoding is enabled */
|
|
||||||
cdc.stat[0] = data & BIT_DECEN;
|
|
||||||
|
|
||||||
/* reset DECI if decoder turned off */
|
/* reset DECI if decoder turned off */
|
||||||
if (!cdc.stat[0])
|
if (!(data & BIT_DECEN))
|
||||||
cdc.ifstat |= BIT_DECI;
|
cdc.ifstat |= BIT_DECI;
|
||||||
|
|
||||||
/* update decoding mode */
|
/* update decoding mode */
|
||||||
|
@ -827,7 +828,7 @@ unsigned short cdc_host_r(void)
|
||||||
if ((int16)cdc.dbc <= 0)
|
if ((int16)cdc.dbc <= 0)
|
||||||
{
|
{
|
||||||
/* reset data byte counter (DBCH bits 4-7 should be set to 1) */
|
/* reset data byte counter (DBCH bits 4-7 should be set to 1) */
|
||||||
cdc.dbc = 0xf000;
|
cdc.dbc = 0xffff;
|
||||||
|
|
||||||
/* clear !DTEN and !DTBSY */
|
/* clear !DTEN and !DTBSY */
|
||||||
cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
|
cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
|
||||||
|
|
|
@ -149,7 +149,7 @@ static void pcd_cdc_event(unsigned int now)
|
||||||
/* reset CDD command wait flag */
|
/* reset CDD command wait flag */
|
||||||
Pico_mcd->s68k_regs[0x4b] = 0xf0;
|
Pico_mcd->s68k_regs[0x4b] = 0xf0;
|
||||||
|
|
||||||
if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) {
|
if ((Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) && (Pico_mcd->s68k_regs[0x37] & 4)) {
|
||||||
elprintf(EL_INTS|EL_CD, "s68k: cdd irq 4");
|
elprintf(EL_INTS|EL_CD, "s68k: cdd irq 4");
|
||||||
pcd_irq_s68k(4, 1);
|
pcd_irq_s68k(4, 1);
|
||||||
}
|
}
|
||||||
|
@ -209,8 +209,7 @@ void pcd_event_schedule(unsigned int now, enum pcd_event event, int after)
|
||||||
|
|
||||||
void pcd_event_schedule_s68k(enum pcd_event event, int after)
|
void pcd_event_schedule_s68k(enum pcd_event event, int after)
|
||||||
{
|
{
|
||||||
if (SekCyclesLeftS68k > after)
|
SekEndRunS68k(after);
|
||||||
SekEndRunS68k(after);
|
|
||||||
|
|
||||||
pcd_event_schedule(SekCyclesDoneS68k(), event, after);
|
pcd_event_schedule(SekCyclesDoneS68k(), event, after);
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ static u32 m68k_reg_read16(u32 a)
|
||||||
// comm flag/cmd/status (0xE-0x2F)
|
// comm flag/cmd/status (0xE-0x2F)
|
||||||
m68k_comm_check(a);
|
m68k_comm_check(a);
|
||||||
d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];
|
d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];
|
||||||
goto end;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
elprintf(EL_UIO, "m68k_regs FIXME invalid read @ %02x", a);
|
elprintf(EL_UIO, "m68k_regs FIXME invalid read @ %02x", a);
|
||||||
|
@ -172,7 +172,8 @@ void m68k_reg_write8(u32 a, u32 d)
|
||||||
elprintf(EL_INTS, "m68k: s68k irq 2");
|
elprintf(EL_INTS, "m68k: s68k irq 2");
|
||||||
pcd_sync_s68k(SekCyclesDone(), 0);
|
pcd_sync_s68k(SekCyclesDone(), 0);
|
||||||
pcd_irq_s68k(2, 1);
|
pcd_irq_s68k(2, 1);
|
||||||
}
|
} else
|
||||||
|
pcd_irq_s68k(2, 0);
|
||||||
return;
|
return;
|
||||||
case 1:
|
case 1:
|
||||||
d &= 3;
|
d &= 3;
|
||||||
|
@ -456,9 +457,9 @@ void s68k_reg_write8(u32 a, u32 d)
|
||||||
case 0x33: // IRQ mask
|
case 0x33: // IRQ mask
|
||||||
elprintf(EL_CDREGS|EL_CD, "s68k irq mask: %02x", d);
|
elprintf(EL_CDREGS|EL_CD, "s68k irq mask: %02x", d);
|
||||||
d &= 0x7e;
|
d &= 0x7e;
|
||||||
if ((d ^ Pico_mcd->s68k_regs[0x33]) & d & PCDS_IEN4) {
|
if ((d ^ Pico_mcd->s68k_regs[0x33]) & PCDS_IEN4) {
|
||||||
// XXX: emulate pending irq instead?
|
// XXX: emulate pending irq instead?
|
||||||
if (Pico_mcd->s68k_regs[0x37] & 4) {
|
if ((d & PCDS_IEN4) && (Pico_mcd->s68k_regs[0x37] & 4)) {
|
||||||
elprintf(EL_INTS, "cdd export irq 4 (unmask)");
|
elprintf(EL_INTS, "cdd export irq 4 (unmask)");
|
||||||
pcd_irq_s68k(4, 1);
|
pcd_irq_s68k(4, 1);
|
||||||
}
|
}
|
||||||
|
@ -474,11 +475,12 @@ void s68k_reg_write8(u32 a, u32 d)
|
||||||
case 0x37: {
|
case 0x37: {
|
||||||
u32 d_old = Pico_mcd->s68k_regs[0x37];
|
u32 d_old = Pico_mcd->s68k_regs[0x37];
|
||||||
Pico_mcd->s68k_regs[0x37] = d & 7;
|
Pico_mcd->s68k_regs[0x37] = d & 7;
|
||||||
if ((d&4) && !(d_old&4)) {
|
if ((d ^ d_old) & 4) {
|
||||||
// ??
|
// ??
|
||||||
pcd_event_schedule_s68k(PCD_EVENT_CDC, 12500000/75);
|
if (d & 4)
|
||||||
|
pcd_event_schedule_s68k(PCD_EVENT_CDC, 12500000/75);
|
||||||
|
|
||||||
if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) {
|
if ((d & 4) && (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4)) {
|
||||||
elprintf(EL_INTS, "cdd export irq 4");
|
elprintf(EL_INTS, "cdd export irq 4");
|
||||||
pcd_irq_s68k(4, 1);
|
pcd_irq_s68k(4, 1);
|
||||||
}
|
}
|
||||||
|
@ -1223,9 +1225,10 @@ static void m68k_mem_setup_cd(void);
|
||||||
|
|
||||||
PICO_INTERNAL void PicoMemSetupCD(void)
|
PICO_INTERNAL void PicoMemSetupCD(void)
|
||||||
{
|
{
|
||||||
if (!Pico_mcd)
|
if (!Pico_mcd) {
|
||||||
Pico_mcd = plat_mmap(0x05000000, sizeof(mcd_state), 0, 0);
|
Pico_mcd = plat_mmap(0x05000000, sizeof(mcd_state), 0, 0);
|
||||||
memset(Pico_mcd, 0, sizeof(mcd_state));
|
memset(Pico_mcd, 0, sizeof(mcd_state));
|
||||||
|
}
|
||||||
pcd_base_address = (Pico.romsize > 0x20000 ? 0x400000 : 0x000000);
|
pcd_base_address = (Pico.romsize > 0x20000 ? 0x400000 : 0x000000);
|
||||||
|
|
||||||
// setup default main68k map
|
// setup default main68k map
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue