This commit is contained in:
yui 2004-08-11 16:09:04 +00:00
parent 06a9293ab4
commit 4a6e8f497a
16 changed files with 285 additions and 98 deletions

View File

@ -22,7 +22,7 @@ static BRESULT dummy(UINT id) {
static const IEVENTFN ieventfn[IEVENT_MAX] = {
dummy, // IEVENT_SIO
dummy, // IEVENT_DMA
ieitem_dmac, // IEVENT_DMA
ieitem_ctc, // IEVENT_CTC0
ieitem_ctc, // IEVENT_CTC1
ieitem_ctc, // IEVENT_CTC2
@ -54,11 +54,14 @@ void ievent_progress(void) {
void ievent_setbit(UINT bit) {
if (CPU_REQIRQ & bit) {
UINT r;
r = CPU_REQIRQ;
if (r & bit) {
return;
}
CPU_REQIRQ |= bit;
if (Z80_ABLEINTERRUPT()) {
if ((!r) && (Z80_ABLEINTERRUPT())) {
nevent_forceexit();
}
}

View File

@ -106,7 +106,7 @@ static void ctcnextevent(CTCCH *ch) {
if (ch->intr) {
return;
}
event = 0x04000000;
event = 0x01000000;
for (i=0; i<3; i++) {
if ((ch->cmd[i] & 0x82) == 0x80) {
clock = ch->count[i];
@ -127,8 +127,11 @@ static void ctcnextevent(CTCCH *ch) {
}
event = min(event, clock);
}
event /= 2;
event *= pccore.multiple;
event /= 2;
if (event == 0) {
event = 1;
}
nevent_set(NEVENT_CTC0 + ch->num, event, neitem_ctc, NEVENT_ABSOLUTE);
}

115
io/dmac.c
View File

@ -1,8 +1,76 @@
#include "compiler.h"
#include "z80core.h"
#include "pccore.h"
#include "iocore.h"
#include "nevent.h"
#include "ievent.h"
static REG8 iswork(const DMAC *d) {
REG8 r;
r = d->cmd;
if ((r & 3) == 0) return(FALSE);
if (d->enable == 0) return(FALSE);
if (d->ENDB_FLG != 0) return(FALSE); // mod
if (r & 2) {
if (d->MACH_FLG != 0) return(FALSE); // mod
}
if (d->mode != 1) {
if ((d->WR[5] ^ d->ready) & 8) return(FALSE);
}
return(TRUE);
}
void dmac_sendready(BRESULT ready) {
REG8 working;
if (!ready) {
dma.working = FALSE;
dma.ready = 8;
}
else {
dma.ready = 0;
working = iswork(&dma);
if (dma.working != working) {
dma.working = working;
nevent_forceexit();
}
}
}
BRESULT ieitem_dmac(UINT id) {
REG8 vect;
if (dma.INT_ENBL) {
vect = 0;
if ((dma.INT_FLG & 1) && (dma.MACH_FLG)) {
vect = 2;
}
else if ((dma.INT_FLG & 2) && (dma.ENDB_FLG)) {
vect = 4;
}
if (vect) {
if (dma.INT_FLG & 0x20) {
vect += (dma.INT_VCT & 0xf9);
}
else {
vect = dma.INT_VCT;
}
Z80_INTERRUPT(vect);
return(TRUE);
}
}
(void)id;
return(FALSE);
}
// ----
static void setdmareaddat(void) {
UINT cnt;
@ -39,8 +107,9 @@ static void setdmareaddat(void) {
void IOOUTCALL dmac_o(UINT port, REG8 value) {
REG8 wr;
REG8 working;
dma.DMA_ENBL = 0;
dma.enable = 0;
if (!dma.WR_CNT) {
wr = 6;
@ -74,7 +143,7 @@ void IOOUTCALL dmac_o(UINT port, REG8 value) {
dma.WR[wr] = value;
switch(wr) {
case 0:
dma.DMA_CMND = (UINT8)(value & 3);
dma.cmd = (UINT8)(value & 3);
if (value & 0x08) {
dma.WR_TBL[dma.WR_CNT++] = offsetof(DMAC, ADR_A.b.l);
}
@ -104,11 +173,11 @@ void IOOUTCALL dmac_o(UINT port, REG8 value) {
dma.WR_TBL[dma.WR_CNT++] = offsetof(DMAC, MACH_BYT);
}
dma.INT_ENBL = (UINT8)((value & 0x20)?1:0);
dma.DMA_ENBL = (UINT8)((value & 0x40)?1:0);
dma.enable = (UINT8)((value & 0x40)?1:0);
break;
case 4:
dma.DMA_MODE = (UINT8)((dma.WR[4] >> 5) & 3);
dma.mode = (UINT8)((dma.WR[4] >> 5) & 3);
if (value & 0x04) {
dma.WR_TBL[dma.WR_CNT++] = offsetof(DMAC, ADR_B.b.l);
}
@ -123,15 +192,16 @@ void IOOUTCALL dmac_o(UINT port, REG8 value) {
case 6:
switch(value) {
case 0x83: // dma disable
dma.DMA_ENBL = 0;
dma.enable = 0;
break;
case 0x87: // dma enable
dma.DMA_ENBL = 1;
dma.enable = 1;
break;
case 0x8b: // re-init status byte
dma.MACH_FLG = dma.ENDB_FLG = 0;
dma.MACH_FLG = 0;
dma.ENDB_FLG = 0;
break;
case 0xa7: // イニシエイトリードシーケンス
@ -147,7 +217,7 @@ void IOOUTCALL dmac_o(UINT port, REG8 value) {
break;
case 0xb3: // force ready
dma.DMA_REDY = (dma.WR[5] & 0x08);
dma.ready = (dma.WR[5] & 0x08);
break;
case 0xbb: // read mask follows
@ -160,13 +230,10 @@ void IOOUTCALL dmac_o(UINT port, REG8 value) {
break;
case 0xc3: // reset
#if 1 // ƒ<><C692>[ƒOƒAƒ‰ƒCƒAƒ“ƒX // ver0.25
dma.DMA_CMND = 0;
dma.DMA_ENBL = 0;
// ƒ<><C692>[ƒOƒAƒ‰ƒCƒAƒ“ƒX // ver0.25
dma.cmd = 0;
dma.enable = 0;
dma.INT_ENBL = 0;
#else
init_dma();
#endif
break;
case 0xc7: // リセットタイミングA
@ -174,13 +241,13 @@ void IOOUTCALL dmac_o(UINT port, REG8 value) {
break;
case 0xcf: // ロード
dma.DMA_MODE = (UINT8)((dma.WR[4] >> 5) & 3);
dma.mode = (UINT8)((dma.WR[4] >> 5) & 3);
dma.CNT_A.w = dma.ADR_A.w;
dma.CNT_B.w = dma.ADR_B.w;
dma.BYT_N.w = 0;
dma.ENDB_FLG = 0;
dma.MACH_FLG = 0; // 0619
dma.DMA_ENBL = 0;
dma.enable = 0;
break;
case 0xd3: // コンティニュー
@ -209,7 +276,7 @@ void IOOUTCALL dmac_o(UINT port, REG8 value) {
dma.BYT_N.w = 0; // 0619
dma.MACH_FLG = 0; // 0619
dma.ENDB_FLG = 0;
dma.DMA_ENBL = 1;
dma.enable = 1;
break;
}
break;
@ -233,6 +300,14 @@ void IOOUTCALL dmac_o(UINT port, REG8 value) {
dma.WR_OFF++;
dma.WR_CNT--;
}
working = iswork(&dma);
if (dma.working != working) {
dma.working = working;
if (working) {
nevent_forceexit();
}
}
(void)port;
}
@ -241,10 +316,10 @@ REG8 IOINPCALL dmac_i(UINT port) {
REG8 ret;
ret = 0xcc;
if (dma.DMA_ENBL) {
if (dma.enable) {
ret |= 0x01;
}
if ((dma.DMA_MODE != 1) && ((dma.WR[5] ^ dma.DMA_REDY) & 8)) {
if ((dma.mode != 1) && ((dma.WR[5] ^ dma.ready) & 8)) {
ret |= 0x02;
}
if (!dma.MACH_FLG) {
@ -270,7 +345,7 @@ REG8 IOINPCALL dmac_i(UINT port) {
void dmac_reset(void) {
ZeroMemory(&dma, sizeof(dma));
dma.DMA_REDY = 8;
dma.ready = 8;
dma.RR = 0x38;
}

View File

@ -18,10 +18,12 @@ typedef union {
#endif
typedef struct {
UINT8 DMA_ENBL;
UINT8 DMA_REDY;
UINT8 DMA_MODE;
UINT8 DMA_CMND;
UINT8 working;
UINT8 enable; // DMA_ENBL
UINT8 ready; // DMA_REDY
UINT8 mode; // DMA_MODE
UINT8 cmd; // DMA_CMND
UINT8 INT_ENBL;
UINT8 INT_FLG;
@ -61,6 +63,9 @@ typedef struct {
extern "C" {
#endif
void dmac_sendready(BRESULT ready);
BRESULT ieitem_dmac(UINT id);
void IOOUTCALL dmac_o(UINT port, REG8 dat); // x1_dma_w
REG8 IOINPCALL dmac_i(UINT port); // x1_dma_r

View File

@ -18,7 +18,7 @@ void nvitem_fdcbusy(UINT id) {
fdc.s.busy = FALSE;
if (fdc.s.bufdir) {
TRACEOUT(("dma ready!"));
dma.DMA_REDY = 0;
dmac_sendready(TRUE);
}
}
@ -208,8 +208,8 @@ static void bufposinc(void) {
}
}
if (!r) {
dma.DMA_REDY = 8;
fdc.s.bufdir = FDCDIR_NONE;
dmac_sendready(FALSE);
}
}
}
@ -301,7 +301,7 @@ void IOOUTCALL fdc_o(UINT port, REG8 value) {
case 0x0d: // フォースインタラプト
setbusy(0); // 必要ない?
// fdc.s.skip = 0; // 000330
dma.DMA_REDY = 8; // ver0.25
dmac_sendready(FALSE);
break;
case 0x0e: // リードトラック
@ -390,7 +390,7 @@ REG8 IOINPCALL fdc_i(UINT port) {
#endif
ret = getstat();
if (!(ret & 0x02)) {
dma.DMA_REDY = 8;
dmac_sendready(FALSE);
}
return(ret);

View File

@ -30,7 +30,7 @@ BRESULT ieitem_scpu(UINT id) {
UINT key;
if ((subcpu.cmdcnt) || (subcpu.datacnt)) {
ievent_set(IEVENT_SUBCPU);
keystat.req_int = 1; // 再送しる
return(FALSE);
}
if (!subcpu.Ex[4][0]) { // 割り込み不要だったら捨てる

View File

@ -85,7 +85,7 @@ void nevent_set(UINT id, SINT32 eventclock, NEVENTCB proc, BRESULT absolute) {
UINT eventid;
UINT i;
// TRACEOUT(("event %d - %xclocks", id, eventclock));
TRACEOUT(("event %d - %xclocks", id, eventclock));
clock = CPU_BASECLOCK - CPU_REMCLOCK;
item = nevent.item + id;

View File

@ -341,11 +341,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (LOWORD(wParam) != WA_INACTIVE) {
scrnmng_update();
mousemng_enable(MOUSEPROC_BG);
soundmng_enable(SNDPROC_MASTER);
// soundmng_enable(SNDPROC_MASTER);
}
else {
// soundmng_disable(SNDPROC_MASTER);
mousemng_disable(MOUSEPROC_BG);
soundmng_disable(SNDPROC_MASTER);
}
break;

View File

@ -11,6 +11,8 @@
#include "parts.h"
#include "z80core.h"
#include "z80c.h"
#include "pccore.h"
#include "iocore.h"
#include "z80c.mcr"
@ -179,13 +181,23 @@ void CPUCALL z80c_execute(void) {
UINT op;
do {
R_Z80R++;
GET_PC_BYTE(op);
Z80_COUNT(cycles_main[op]);
z80c_mainop[op]();
z80dmap();
} while(CPU_REMCLOCK > 0);
if (!dma.working) {
do {
R_Z80R++;
GET_PC_BYTE(op);
Z80_COUNT(cycles_main[op]);
z80c_mainop[op]();
} while(CPU_REMCLOCK > 0);
}
else {
do {
R_Z80R++;
GET_PC_BYTE(op);
Z80_COUNT(cycles_main[op]);
z80c_mainop[op]();
z80dmap();
} while(CPU_REMCLOCK > 0);
}
}
void CPUCALL z80c_step(void) {

View File

@ -64,7 +64,7 @@ static REG8 CPUCALL _cb_sra(REG8 v) {
REG8 ret;
ret = (((char)v) / 2);
ret = (((SINT8)v) >> 1);
R_Z80F = ZSPtable[ret] | (v & 1);
return(ret);
}

View File

@ -2,28 +2,20 @@
#include "z80core.h"
#include "pccore.h"
#include "iocore.h"
#include "ievent.h"
void z80dmap(void) {
REG8 r;
UINT16 *off1;
UINT16 *off2;
REG8 flag1;
REG8 flag2;
UINT addr;
REG8 dat;
REG8 vect;
r = dma.DMA_CMND;
if ((r & 3) == 0) return;
if (dma.DMA_ENBL == 0) return;
if (dma.ENDB_FLG != 0) return; // mod
if (r & 2) {
if (dma.MACH_FLG != 0) return; // mod
}
if (dma.DMA_MODE != 1) {
if ((dma.WR[5] ^ dma.DMA_REDY) & 8) return;
if (!dma.working) {
return;
}
if (dma.WR[0] & 4) {
@ -40,12 +32,6 @@ void z80dmap(void) {
}
do { // dma_lp
if (dma.ENDB_FLG) {
break;
}
if ((dma.DMA_CMND & 2) && (dma.MACH_FLG)) {
break;
}
addr = *off1;
if (flag1 & 8) {
dat = iocore_inp(addr);
@ -53,7 +39,7 @@ void z80dmap(void) {
else {
dat = mem_read8(addr);
}
if (dma.DMA_CMND & 1) {
if (dma.cmd & 1) {
addr = *off2;
if (flag2 & 8) {
iocore_out(addr, dat);
@ -62,14 +48,16 @@ void z80dmap(void) {
mem_write8(addr, dat);
}
}
if (dma.DMA_CMND & 2) {
if (dma.cmd & 2) {
if (!((dat ^ dma.MACH_BYT) & (~dma.MASK_BYT))) {
dma.working = FALSE;
dma.MACH_FLG = 1;
}
}
if (dma.DMA_MODE != 1) {
dma.DMA_STOP = (dma.WR[5] ^ dma.DMA_REDY) & 8;
if (dma.mode != 1) {
dma.DMA_STOP = (dma.WR[5] ^ dma.ready) & 8;
if (dma.DMA_STOP) {
dma.working = FALSE; // 既にセットされてる筈だが
goto dma_stop;
}
}
@ -83,32 +71,24 @@ void z80dmap(void) {
dma_stop:
dma.BYT_N.w++;
if (dma.BYT_N.w == 0) {
dma.working = FALSE;
dma.ENDB_FLG = 1;
break;
goto intr;
}
if ((dma.BYT_L.w) && (dma.BYT_L.w != 0xffff) && (dma.BYT_N.w >= (dma.BYT_L.w + 1))) {
dma.working = FALSE;
dma.ENDB_FLG = 1;
break;
goto intr;
}
} while(dma.DMA_MODE);
if (!dma.working) {
goto intr;
}
} while(dma.mode);
return;
intr:
if (dma.INT_ENBL) {
vect = 0;
if ((dma.INT_FLG & 1) && (dma.MACH_FLG)) {
vect = 2;
}
else if ((dma.INT_FLG & 2) && (dma.ENDB_FLG)) {
vect = 4;
}
if (vect) {
if (dma.INT_FLG & 0x20) {
vect += (dma.INT_VCT & 0xf9);
}
else {
vect = dma.INT_VCT;
}
z80c_interrupt(vect);
}
ievent_set(IEVENT_DMA);
}
}

View File

@ -14,8 +14,8 @@ void MEMCALL mem_write8(UINT addr, REG8 value);
void MEMCALL mem_write16(UINT addr, REG16 value);
SINT MEMCALL mem_read8s(UINT addr);
// REG8 MEMCALL Z80_RDMEM(REG16 addr);
// void MEMCALL Z80_WRMEM(REG16 addr, REG8 value);
#define z80mem_read8(a) mem_read8(a)
#define z80mem_write8(a) mem_write8(a)
#ifdef __cplusplus
}

View File

@ -2,8 +2,101 @@
#include "z80core.h"
#include "pccore.h"
#include "iocore.h"
#include "ievent.h"
void z80dmap(void) {
UINT16 *off1;
UINT16 *off2;
REG8 flag1;
REG8 flag2;
UINT addr;
REG8 dat;
if (!dma.working) {
return;
}
if (dma.WR[0] & 4) {
off1 = &dma.CNT_A.w;
flag1 = dma.WR[1];
off2 = &dma.CNT_B.w;
flag2 = dma.WR[2];
}
else {
off2 = &dma.CNT_A.w;
flag2 = dma.WR[1];
off1 = &dma.CNT_B.w;
flag1 = dma.WR[2];
}
do { // dma_lp
addr = *off1;
if (flag1 & 8) {
dat = iocore_inp(addr);
}
else {
dat = z80mem_read8(addr);
}
if (dma.cmd & 1) {
addr = *off2;
if (flag2 & 8) {
iocore_out(addr, dat);
}
else {
z80mem_write8(addr, dat);
}
}
if (dma.cmd & 2) {
if (!((dat ^ dma.MACH_BYT) & (~dma.MASK_BYT))) {
dma.working = FALSE;
dma.MACH_FLG = 1;
}
}
if (dma.mode != 1) {
dma.DMA_STOP = (dma.WR[5] ^ dma.ready) & 8;
if (dma.DMA_STOP) {
dma.working = FALSE; // 既にセットされてる筈だが
goto dma_stop;
}
}
if (!(flag1 & 0x20)) {
*off1 += (flag1 & 0x10)?1:-1;
}
if (!(flag2 & 0x20)) {
*off2 += (flag2 & 0x10)?1:-1;
}
dma_stop:
dma.BYT_N.w++;
if (dma.BYT_N.w == 0) {
dma.working = FALSE;
dma.ENDB_FLG = 1;
goto intr;
}
if ((dma.BYT_L.w) && (dma.BYT_L.w != 0xffff) && (dma.BYT_N.w >= (dma.BYT_L.w + 1))) {
dma.working = FALSE;
dma.ENDB_FLG = 1;
goto intr;
}
if (!dma.working) {
goto intr;
}
} while(dma.mode);
return;
intr:
if (dma.INT_ENBL) {
ievent_set(IEVENT_DMA);
}
}
#if 0 // old
LABEL void z80dmap(void) {
__asm {
@ -145,4 +238,5 @@ dma_outport: call iocore_out
jmp dmadstend
}
}
#endif

View File

@ -12,13 +12,14 @@ section .text
global _z80x_step
extern _z80core
extern _z80dmap
extern memfetch
extern memrd16_ecx_ax
extern memwr16_ecx_dx
extern _cycles_main
extern opcode_main
extern _z80dmap
extern _dma
align 16
_z80x_ableinterrupt:
@ -95,7 +96,22 @@ _z80x_nonmaskedinterrupt:
_z80x_execute push ebx
push edi
mov edi, _z80core
cmp byte [_dma], 0
jne short .dmalp
.lp: inc byte [edi + R_Z80R]
movzx ecx, word [edi + R_Z80PC]
inc word [edi + R_Z80PC]
call memfetch
movzx edx, byte [_cycles_main + eax]
Z80WORK edx
call dword [opcode_main + eax*4]
mov eax, [edi + z80core_t.remainclock]
cmp eax, byte 0
jg short .lp
.ed: pop edi
pop ebx
ret
.dmalp: inc byte [edi + R_Z80R]
movzx ecx, word [edi + R_Z80PC]
inc word [edi + R_Z80PC]
call memfetch
@ -105,10 +121,9 @@ _z80x_execute push ebx
call _z80dmap
mov eax, [edi + z80core_t.remainclock]
cmp eax, byte 0
jg short .lp
pop edi
pop ebx
ret
jg short .dmalp
jmp short .ed
align 16
_z80x_step: push ebx

View File

@ -3,8 +3,8 @@
extern "C" {
#endif
UINT8 __fastcall memrd8_ecx_al(UINT addr);
void __fastcall memwr8_ecx_dl(UINT addr, UINT8 value);
UINT8 __fastcall z80mem_read8(UINT addr);
void __fastcall z80mem_write8(UINT addr, UINT8 value);
#ifdef __cplusplus
}

View File

@ -9,8 +9,8 @@ section .bss
section .text
global @memrd8_ecx_al@4
global @memwr8_ecx_dl@8
global @z80mem_read8@4
global @z80mem_write8@8
global lea_ecx_ecx
global memfetch
@ -40,7 +40,7 @@ memfetch: cmp ecx, 8000h
ret
align 16
@memrd8_ecx_al@4:
@z80mem_read8@4:
memrd8_ecx_al: cmp ecx, 8000h
jc short .low
mov al, [_mMAIN + ecx]
@ -59,7 +59,7 @@ memrd8_ecx_dl: cmp ecx, 8000h
ret
align 16
@memwr8_ecx_dl@8:
@z80mem_write8@8:
memwr8_ecx_dl: cmp ecx, 8000h
jc short .low
mov [_mMAIN + ecx], dl