|
|
| version 1.3, 2004/08/05 04:53:15 | version 1.11, 2009/03/23 15:02:25 |
|---|---|
| Line 2 | Line 2 |
| #include "z80core.h" | #include "z80core.h" |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | #include "iocore.h" |
| #include "ievent.h" | |
| LABEL void z80dmap(void) { | void z80dmap(void) { |
| __asm { | DMACNT *cnt1; |
| mov al, dma.DMA_CMND | DMACNT *cnt2; |
| test al, 3 | UINT addr; |
| je dmaintend | REG8 dat; |
| cmp dma.DMA_ENBL, 0 | REG8 flag1; |
| je dmaintend | REG8 flag2; |
| cmp dma.ENDB_FLG, 0 | |
| jne dmaintend | #if !defined(DMAS_STOIC) |
| test al, 2 | if (!dma.working) |
| je ckcntmode | #else |
| cmp dma.MACH_FLG, 0 | if (!(dma.flag & DMAF_WORKING)) |
| jne short dmaintend | #endif |
| ckcntmode: cmp dma.DMA_MODE, 1 | { |
| je dmaintmain | return; |
| mov al, dma.WR[5] | } |
| xor al, dma.DMA_REDY | |
| test al, 8 | if (dma.WR0 & 4) { |
| je dmaintmain | cnt1 = &dma.cnt_a; |
| dmaintend: ret | cnt2 = &dma.cnt_b; |
| } | |
| dmaintmain: push ebx | else { |
| mov ebx, offset dma.CNT_A | cnt2 = &dma.cnt_a; |
| mov ecx, offset dma.CNT_B | cnt1 = &dma.cnt_b; |
| } | |
| mov dx, word ptr (dma.WR[1]) | |
| test dma.WR[0], 4 | flag1 = cnt1->b.flag; |
| jne dma_lp | flag2 = cnt2->b.flag; |
| xchg ebx, ecx | do { // dma_lp |
| xchg dl, dh | CPU_REMCLOCK -= 6; |
| #if !defined(DMAS_STOIC) | |
| dma_lp: cmp dma.ENDB_FLG, 0 | if (dma.increment) |
| jne dmalpend | #else |
| test dma.DMA_CMND, 2 | if (dma.flag & DMAF_INCREMENT) |
| je dma_lpst | #endif |
| cmp dma.MACH_FLG, 0 | { |
| jne dmalpend | if (!(flag1 & 0x20)) { |
| dma_lpst: | cnt1->w.addr += (flag1 & 0x10)?1:-1; |
| push ecx | } |
| movzx ecx, word ptr [ebx] | if (!(flag2 & 0x20)) { |
| test dl, 8 | cnt2->w.addr += (flag2 & 0x10)?1:-1; |
| jne dma_inport | } |
| push edx | } |
| call memrd8_ecx_al | else { |
| pop edx | #if !defined(DMAS_STOIC) |
| dmasrcend: pop ecx | dma.increment = 1; |
| #else | |
| test dma.DMA_CMND, 1 | dma.flag |= DMAF_INCREMENT; |
| je dmadstend | #endif |
| } | |
| push eax | addr = cnt1->w.addr; |
| push ecx | if (flag1 & 8) { |
| push edx | dat = iocore_inp(addr); |
| movzx ecx, word ptr [ecx] | /* TRACEOUT(("dma r %.4x - %.2x", addr, dat)); */ |
| mov dl, al | } |
| test dh, 8 | else { |
| jne dma_outport | dat = z80mem_read8(addr); |
| call memwr8_ecx_dl | } |
| dmadstend: pop edx | if (dma.WR0 & 2) { |
| pop ecx | if (!((dat ^ dma.MACH_BYT) & (~dma.MASK_BYT))) { |
| pop eax | #if !defined(DMAS_STOIC) |
| dma.working = FALSE; | |
| test dma.DMA_CMND, 2 | dma.MACH_FLG = 1; |
| je dmamachcend | #else |
| xor al, dma.MACH_BYT | dma.flag &= ~(DMAF_WORKING | DMAF_MACH); |
| mov ah, dma.MASK_BYT | #endif |
| not ah | } |
| and al, ah | } |
| jne short dmamachcend | if (dma.WR0 & 1) { |
| mov dma.MACH_FLG, 1 | addr = cnt2->w.addr; |
| dmamachcend: | if (flag2 & 8) { |
| cmp dma.DMA_MODE, 1 | iocore_out(addr, dat); |
| je forcesrcaddr | } |
| mov al, dma.WR[5] | else { |
| xor al, dma.DMA_REDY | z80mem_write8(addr, dat); |
| and al, 8 | /* TRACEOUT(("dma w %.4x - %.2x", addr, dat)); */ |
| mov dma.DMA_STOP, al | } |
| jne dmadststpend | } |
| forcesrcaddr: test dl, 20h | dma.leng.w.n++; |
| jne dmasrcstpend | if (dma.leng.w.n == 0) { |
| test dl, 10h | #if !defined(DMAS_STOIC) |
| je dmasrcdec | dma.working = FALSE; |
| inc word ptr [ebx] | dma.ENDB_FLG = 1; |
| jmp dmasrcstpend | #else |
| dmasrcdec: dec word ptr [ebx] | dma.flag &= ~(DMAF_WORKING | DMAF_ENDB); |
| dmasrcstpend: | #endif |
| test dh, 20h | } |
| jne dmadststpend | else if ((dma.leng.w.l) && ((dma.leng.w.n - 1) >= dma.leng.w.l)) { |
| test dh, 10h | #if !defined(DMAS_STOIC) |
| je dmadstdec | dma.working = FALSE; |
| inc word ptr [ecx] | dma.ENDB_FLG = 1; |
| jmp dmadststpend | #else |
| dmadstdec: dec word ptr [ecx] | dma.flag &= ~(DMAF_WORKING | DMAF_ENDB); |
| dmadststpend: | #endif |
| inc dma.BYT_N.w | } |
| je dmaforceend | #if !defined(DMAS_STOIC) |
| mov ax, dma.BYT_L.w | if (!dma.working) |
| or ax, ax | #else |
| je dmplpedch // BYT_L == 0なら無制限? | if (!(dma.flag & DMAF_WORKING)) |
| inc ax | #endif |
| je dmplpedch // ver0.25 | { |
| cmp ax, dma.BYT_N.w | goto intr; |
| ja dmplpedch | } |
| dmaforceend: mov dma.ENDB_FLG, 1 | } while(dma.mode); |
| jmp dmalpend | return; |
| dmplpedch: cmp dma.DMA_MODE, 0 | intr: |
| jne dma_lp | if (dma.INT_ENBL) { |
| dmalpend: | ievent_set(IEVENT_DMA); |
| pop ebx | |
| cmp dma.INT_ENBL, 0 | |
| je dmaintrptend | |
| mov dl, 2 | |
| mov al, dma.INT_FLG | |
| test al, 1 | |
| je dmaintrpt2ck | |
| cmp dma.MACH_FLG, 0 | |
| jne dmaintrptcall | |
| dmaintrpt2ck: mov dl, 4 | |
| test al, 2 | |
| je dmaintrptend | |
| cmp dma.ENDB_FLG, 0 | |
| je dmaintrptend | |
| dmaintrptcall: movzx ecx, dma.INT_VCT | |
| test al, 20h | |
| je dma_intrpt | |
| and cl, 0f9h | |
| or cl, dl | |
| dma_intrpt: jmp z80x_interrupt | |
| dmaintrptend: ret | |
| dma_inport: push edx | |
| push ebx | |
| cmp cx, 0ffbh | |
| jne Z80inport | |
| mov fdcdummyread, 0 | |
| Z80inport: call iocore_inp | |
| pop ebx | |
| pop edx | |
| jmp dmasrcend | |
| dma_outport: push ebx | |
| cmp cx, 0ffbh | |
| jne Z80outport | |
| cmp ppi.IO_MODE, 0 | |
| jne Z80outport | |
| mov fdcdummyread, 0 | |
| Z80outport: call iocore_out | |
| pop ebx | |
| jmp dmadstend | |
| } | } |
| } | } |