|
|
| version 1.3, 2003/12/08 00:55:32 | version 1.12, 2005/02/07 14:46:11 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "cpucore.h" | |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | #include "iocore.h" |
| #include "sound.h" | #include "sound.h" |
| #include "cs4231.h" | #include "cs4231.h" |
| #include "sasiio.h" | |
| void DMACCALL dma_dummyout(REG8 data) { | void DMACCALL dma_dummyout(REG8 data) { |
| Line 21 REG8 DMACCALL dma_dummyproc(REG8 func) { | Line 23 REG8 DMACCALL dma_dummyproc(REG8 func) { |
| return(0); | return(0); |
| } | } |
| static const DMAPROC dmaproc[] = { | |
| {dma_dummyout, dma_dummyin, dma_dummyproc}, // NONE | |
| {fdc_datawrite, fdc_dataread, fdc_dmafunc}, // 2HD | |
| {fdc_datawrite, fdc_dataread, fdc_dmafunc}, // 2DD | |
| #if defined(SUPPORT_SASI) | |
| {sasi_datawrite, sasi_dataread, sasi_dmafunc}, // SASI | |
| #else | |
| {dma_dummyout, dma_dummyin, dma_dummyproc}, // SASI | |
| #endif | |
| {dma_dummyout, dma_dummyin, dma_dummyproc}, // SCSI | |
| #if !defined(DISABLE_SOUND) | |
| {dma_dummyout, dma_dummyin, cs4231dmafunc}, // CS4231 | |
| #else | |
| {dma_dummyout, dma_dummyin, dma_dummyproc}, // SASI | |
| #endif | |
| }; | |
| // ---- | // ---- |
| Line 37 void dmac_check(void) { | Line 56 void dmac_check(void) { |
| if ((!(dmac.mask & bit)) && (ch->ready)) { | if ((!(dmac.mask & bit)) && (ch->ready)) { |
| if (!(dmac.work & bit)) { | if (!(dmac.work & bit)) { |
| dmac.work |= bit; | dmac.work |= bit; |
| if (ch->extproc(DMAEXT_START)) { | if (ch->proc.extproc(DMAEXT_START)) { |
| dmac.stat &= ~bit; // ver0.27 | dmac.stat &= ~bit; |
| dmac.working |= bit; | dmac.working |= bit; |
| workchg = TRUE; | workchg = TRUE; |
| } | } |
| Line 48 void dmac_check(void) { | Line 67 void dmac_check(void) { |
| if (dmac.work & bit) { | if (dmac.work & bit) { |
| dmac.work &= ~bit; | dmac.work &= ~bit; |
| dmac.working &= ~bit; | dmac.working &= ~bit; |
| ch->extproc(DMAEXT_BREAK); | ch->proc.extproc(DMAEXT_BREAK); |
| workchg = TRUE; | workchg = TRUE; |
| } | } |
| } | } |
| Line 60 void dmac_check(void) { | Line 79 void dmac_check(void) { |
| } | } |
| } | } |
| UINT dmac_getdatas(DMACH dmach, UINT8 *buf, UINT size) { | |
| UINT leng; | |
| UINT32 addr; | |
| UINT i; | |
| leng = min(dmach->leng.w, size); | |
| if (leng) { | |
| addr = dmach->adrs.d; // + mask | |
| if (!(dmach->mode & 0x20)) { // dir + | |
| for (i=0; i<leng; i++) { | |
| buf[i] = MEMP_READ8(addr + i); | |
| } | |
| dmach->adrs.d += leng; | |
| } | |
| else { // dir - | |
| for (i=0; i<leng; i++) { | |
| buf[i] = MEMP_READ8(addr - i); | |
| } | |
| dmach->adrs.d -= leng; | |
| } | |
| dmach->leng.w -= leng; | |
| if (dmach->leng.w == 0) { | |
| dmach->proc.extproc(DMAEXT_END); | |
| } | |
| } | |
| return(leng); | |
| } | |
| // ---- I/O | // ---- I/O |
| Line 70 static void IOOUTCALL dmac_o01(UINT port | Line 118 static void IOOUTCALL dmac_o01(UINT port |
| dmach = dmac.dmach + ((port >> 2) & 3); | dmach = dmac.dmach + ((port >> 2) & 3); |
| lh = dmac.lh; | lh = dmac.lh; |
| dmac.lh = lh ^ 1; | dmac.lh = (UINT8)(lh ^ 1); |
| dmach->adrs.b[lh + DMA32_LOW] = dat; | dmach->adrs.b[lh + DMA32_LOW] = dat; |
| dmach->adrsorg.b[lh] = dat; | dmach->adrsorg.b[lh] = dat; |
| } | } |
| Line 140 static void IOOUTCALL dmac_o21(UINT port | Line 188 static void IOOUTCALL dmac_o21(UINT port |
| DMACH dmach; | DMACH dmach; |
| dmach = dmac.dmach + (((port >> 1) + 1) & 3); | dmach = dmac.dmach + (((port >> 1) + 1) & 3); |
| #if defined(CPUCORE_IA32) | |
| dmach->adrs.b[DMA32_HIGH + DMA16_LOW] = dat; | dmach->adrs.b[DMA32_HIGH + DMA16_LOW] = dat; |
| #else | |
| // IA16では ver0.75で無効、ver0.76で修正 | |
| dmach->adrs.b[DMA32_HIGH + DMA16_LOW] = dat & 0x0f; | |
| #endif | |
| } | |
| static void IOOUTCALL dmac_o29(UINT port, REG8 dat) { | |
| DMACH dmach; | |
| dmach = dmac.dmach + (dat & 3); | |
| dmach->bound = dat; | |
| (void)port; | |
| } | } |
| static REG8 IOINPCALL dmac_i01(UINT port) { | static REG8 IOINPCALL dmac_i01(UINT port) { |
| Line 151 static REG8 IOINPCALL dmac_i01(UINT port | Line 213 static REG8 IOINPCALL dmac_i01(UINT port |
| dmach = dmac.dmach + ((port >> 2) & 3); | dmach = dmac.dmach + ((port >> 2) & 3); |
| lh = dmac.lh; | lh = dmac.lh; |
| dmac.lh = lh ^ 1; | dmac.lh = lh ^ 1; |
| return(dmach->leng.b[lh]); | return(dmach->adrs.b[lh + DMA32_LOW]); |
| } | } |
| static REG8 IOINPCALL dmac_i03(UINT port) { | static REG8 IOINPCALL dmac_i03(UINT port) { |
| Line 162 static REG8 IOINPCALL dmac_i03(UINT port | Line 224 static REG8 IOINPCALL dmac_i03(UINT port |
| dmach = dmac.dmach + ((port >> 2) & 3); | dmach = dmac.dmach + ((port >> 2) & 3); |
| lh = dmac.lh; | lh = dmac.lh; |
| dmac.lh = lh ^ 1; | dmac.lh = lh ^ 1; |
| return(dmach->adrs.b[lh + DMA32_LOW]); | return(dmach->leng.b[lh]); |
| } | } |
| static REG8 IOINPCALL dmac_i11(UINT port) { | static REG8 IOINPCALL dmac_i11(UINT port) { |
| Line 186 static const IOINP dmaci00[16] = { | Line 248 static const IOINP dmaci00[16] = { |
| dmac_i11, NULL, NULL, NULL, | dmac_i11, NULL, NULL, NULL, |
| NULL, NULL, NULL, NULL}; | NULL, NULL, NULL, NULL}; |
| static const IOOUT dmaco21[4] = { | static const IOOUT dmaco21[8] = { |
| dmac_o21, dmac_o21, dmac_o21, dmac_o21}; | dmac_o21, dmac_o21, dmac_o21, dmac_o21, |
| dmac_o29, NULL, NULL, NULL}; | |
| void dmac_reset(void) { | void dmac_reset(void) { |
| int i; | |
| ZeroMemory(&dmac, sizeof(dmac)); | ZeroMemory(&dmac, sizeof(dmac)); |
| dmac.lh = DMA16_LOW; | dmac.lh = DMA16_LOW; |
| dmac.mask = 0xf; | dmac.mask = 0xf; |
| for (i=0; i<4; i++) { | dmac_procset(); |
| dmac.dmach[i].outproc = dma_dummyout; | |
| dmac.dmach[i].inproc = dma_dummyin; | |
| dmac.dmach[i].extproc = dma_dummyproc; | |
| } | |
| dmac.dmach[0].extproc = cs4231dmafunc; | |
| dmac.dmach[DMA_2HD].inproc = fdc_DataRegRead; | |
| dmac.dmach[DMA_2HD].outproc = fdc_DataRegWrite; | |
| dmac.dmach[DMA_2HD].extproc = fdc_dmafunc; | |
| dmac.dmach[DMA_2DD].inproc = fdc_DataRegRead; | |
| dmac.dmach[DMA_2DD].outproc = fdc_DataRegWrite; | |
| dmac.dmach[DMA_2DD].extproc = fdc_dmafunc; | |
| // TRACEOUT(("sizeof(_DMACH) = %d", sizeof(_DMACH))); | // TRACEOUT(("sizeof(_DMACH) = %d", sizeof(_DMACH))); |
| } | } |
| Line 216 void dmac_bind(void) { | Line 265 void dmac_bind(void) { |
| iocore_attachsysoutex(0x0001, 0x0ce1, dmaco00, 16); | iocore_attachsysoutex(0x0001, 0x0ce1, dmaco00, 16); |
| iocore_attachsysinpex(0x0001, 0x0ce1, dmaci00, 16); | iocore_attachsysinpex(0x0001, 0x0ce1, dmaci00, 16); |
| iocore_attachsysoutex(0x0021, 0x0cf1, dmaco21, 4); | iocore_attachsysoutex(0x0021, 0x0cf1, dmaco21, 8); |
| } | |
| // ---- | |
| static void dmacset(REG8 channel) { | |
| DMADEV *dev; | |
| DMADEV *devterm; | |
| UINT dmadev; | |
| dev = dmac.device; | |
| devterm = dev + dmac.devices; | |
| dmadev = DMADEV_NONE; | |
| while(dev < devterm) { | |
| if (dev->channel == channel) { | |
| dmadev = dev->device; | |
| } | |
| dev++; | |
| } | |
| if (dmadev >= NELEMENTS(dmaproc)) { | |
| dmadev = 0; | |
| } | |
| // TRACEOUT(("dmac set %d - %d", channel, dmadev)); | |
| dmac.dmach[channel].proc = dmaproc[dmadev]; | |
| } | |
| void dmac_procset(void) { | |
| REG8 i; | |
| for (i=0; i<4; i++) { | |
| dmacset(i); | |
| } | |
| } | |
| void dmac_attach(REG8 device, REG8 channel) { | |
| dmac_detach(device); | |
| if (dmac.devices < NELEMENTS(dmac.device)) { | |
| dmac.device[dmac.devices].device = device; | |
| dmac.device[dmac.devices].channel = channel; | |
| dmac.devices++; | |
| dmacset(channel); | |
| } | |
| } | |
| void dmac_detach(REG8 device) { | |
| DMADEV *dev; | |
| DMADEV *devterm; | |
| REG8 ch; | |
| dev = dmac.device; | |
| devterm = dev + dmac.devices; | |
| while(dev < devterm) { | |
| if (dev->device == device) { | |
| break; | |
| } | |
| dev++; | |
| } | |
| if (dev < devterm) { | |
| ch = dev->channel; | |
| dev++; | |
| while(dev < devterm) { | |
| *(dev - 1) = *dev; | |
| dev++; | |
| } | |
| dmac.devices--; | |
| dmacset(ch); | |
| } | |
| } | } |