| version 1.1, 2003/10/16 17:57:55 | version 1.9, 2005/02/07 14:46:11 | 
| Line 1 | Line 1 | 
 | #include        "compiler.h" | #include        "compiler.h" | 
| #include        "memory.h" | #include        "cpucore.h" | 
|  | #include        "egcmem.h" | 
 | #include        "pccore.h" | #include        "pccore.h" | 
 | #include        "iocore.h" | #include        "iocore.h" | 
 |  | #include        "gdc_sub.h" | 
 | #include        "gdc_pset.h" | #include        "gdc_pset.h" | 
 | #include        "vram.h" | #include        "vram.h" | 
 |  |  | 
 |  |  | 
 | static void MEMCALL _nop(GDCPSET pset, UINT addr, UINT bit) { | static void MEMCALL _nop(GDCPSET pset, UINT addr, UINT bit) { | 
 |  |  | 
| pset->pattern = (pset->pattern << 1) + (pset->pattern >> 15); | (void)pset; | 
 | (void)addr; | (void)addr; | 
 | (void)bit; | (void)bit; | 
 | } | } | 
 |  |  | 
| static void MEMCALL _replace(GDCPSET pset, UINT addr, UINT bit) { | static void MEMCALL _replace0(GDCPSET pset, UINT addr, UINT bit) { | 
 |  |  | 
| vramupdate[addr] |= pset->update; | vramupdate[addr] |= pset->update.b[0]; | 
| if (pset->pattern & 0x8000) { | pset->base.ptr[addr] &= ~(0x80 >> bit); | 
| pset->pattern <<= 1; | } | 
| pset->pattern++; |  | 
| pset->base[addr] |= (0x80 >> bit); | static void MEMCALL _replace1(GDCPSET pset, UINT addr, UINT bit) { | 
| } |  | 
| else { | vramupdate[addr] |= pset->update.b[0]; | 
| pset->pattern <<= 1; | pset->base.ptr[addr] |= (0x80 >> bit); | 
| pset->base[addr] &= ~(0x80 >> bit); |  | 
| } |  | 
 | } | } | 
 |  |  | 
 | static void MEMCALL _complemnt(GDCPSET pset, UINT addr, UINT bit) { | static void MEMCALL _complemnt(GDCPSET pset, UINT addr, UINT bit) { | 
 |  |  | 
| if (pset->pattern & 0x8000) { | vramupdate[addr] |= pset->update.b[0]; | 
| pset->pattern <<= 1; | pset->base.ptr[addr] ^= (0x80 >> bit); | 
| pset->pattern++; |  | 
| vramupdate[addr] |= pset->update; |  | 
| pset->base[addr] ^= (0x80 >> bit); |  | 
| } |  | 
| else { |  | 
| pset->pattern <<= 1; |  | 
| } |  | 
 | } | } | 
 |  |  | 
 | static void MEMCALL _clear(GDCPSET pset, UINT addr, UINT bit) { | static void MEMCALL _clear(GDCPSET pset, UINT addr, UINT bit) { | 
 |  |  | 
| if (pset->pattern & 0x8000) { | vramupdate[addr] |= pset->update.b[0]; | 
| pset->pattern <<= 1; | pset->base.ptr[addr] &= ~(0x80 >> bit); | 
| pset->pattern++; |  | 
| vramupdate[addr] |= pset->update; |  | 
| pset->base[addr] &= ~(0x80 >> bit); |  | 
| } |  | 
| else { |  | 
| pset->pattern <<= 1; |  | 
| } |  | 
 | } | } | 
 |  |  | 
 | static void MEMCALL _set(GDCPSET pset, UINT addr, UINT bit) { | static void MEMCALL _set(GDCPSET pset, UINT addr, UINT bit) { | 
 |  |  | 
| if (pset->pattern & 0x8000) { | vramupdate[addr] |= pset->update.b[0]; | 
| pset->pattern <<= 1; | pset->base.ptr[addr] |= (0x80 >> bit); | 
| pset->pattern++; |  | 
| vramupdate[addr] |= pset->update; |  | 
| pset->base[addr] |= (0x80 >> bit); |  | 
| } |  | 
| else { |  | 
| pset->pattern <<= 1; |  | 
| } |  | 
 | } | } | 
 |  |  | 
 | static void MEMCALL _tdw(GDCPSET pset, UINT addr, UINT bit) { |  | 
 |  |  | 
| BYTE    *ptr; | // ---- grcg | 
 |  |  | 
| if (pset->pattern & 0x8000) { | static void MEMCALL withtdw(GDCPSET pset, UINT addr, UINT bit) { | 
| pset->pattern <<= 1; |  | 
| pset->pattern++; | UINT8   *ptr; | 
| vramupdate[addr] |= pset->update; |  | 
| ptr = pset->base + addr; | addr &= ~1; | 
| ptr[VRAM_B] = grcg.tile[0].b[0]; | *(UINT16 *)(vramupdate + addr) |= pset->update.w; | 
| ptr[VRAM_R] = grcg.tile[1].b[0]; | ptr = pset->base.ptr + addr; | 
| ptr[VRAM_G] = grcg.tile[2].b[0]; | *(UINT16 *)(ptr + VRAM_B) = grcg.tile[0].w; | 
| ptr[VRAM_E] = grcg.tile[3].b[0]; | *(UINT16 *)(ptr + VRAM_R) = grcg.tile[1].w; | 
| } | *(UINT16 *)(ptr + VRAM_G) = grcg.tile[2].w; | 
| else { | *(UINT16 *)(ptr + VRAM_E) = grcg.tile[3].w; | 
| pset->pattern <<= 1; |  | 
| } |  | 
 | (void)bit; | (void)bit; | 
 | } | } | 
 |  |  | 
| static void MEMCALL _rmw(GDCPSET pset, UINT addr, UINT bit) { | static void MEMCALL withrmw(GDCPSET pset, UINT addr, UINT bit) { | 
 |  |  | 
| BYTE    *ptr; | UINT8   *ptr; | 
| BYTE    data; | UINT8   data; | 
| BYTE    mask; | UINT8   mask; | 
|  |  | 
| if (pset->pattern & 0x8000) { | vramupdate[addr] |= pset->update.b[0]; | 
| pset->pattern <<= 1; | ptr = pset->base.ptr + addr; | 
| pset->pattern++; | data = (0x80 >> bit); | 
| vramupdate[addr] |= pset->update; | mask = ~data; | 
| ptr = pset->base + addr; | ptr[VRAM_B] &= mask; | 
| data = (0x80 >> bit); | ptr[VRAM_B] |= data & grcg.tile[0].b[0]; | 
| mask = ~bit; | ptr[VRAM_R] &= mask; | 
| ptr[VRAM_B] &= mask; | ptr[VRAM_R] |= data & grcg.tile[1].b[0]; | 
| ptr[VRAM_B] |= bit & grcg.tile[0].b[0]; | ptr[VRAM_G] &= mask; | 
| ptr[VRAM_R] &= mask; | ptr[VRAM_G] |= data & grcg.tile[2].b[0]; | 
| ptr[VRAM_R] |= bit & grcg.tile[1].b[0]; | ptr[VRAM_E] &= mask; | 
| ptr[VRAM_G] &= mask; | ptr[VRAM_E] |= data & grcg.tile[3].b[0]; | 
| ptr[VRAM_G] |= bit & grcg.tile[2].b[0]; | } | 
| ptr[VRAM_E] &= mask; |  | 
| ptr[VRAM_E] |= bit & grcg.tile[3].b[0]; |  | 
| } | // ---- egc | 
| else { |  | 
| pset->pattern <<= 1; | static void MEMCALL withegc(GDCPSET pset, UINT addr, UINT bit) { | 
|  |  | 
|  | REG16   data; | 
|  |  | 
|  | data = (0x80 >> bit); | 
|  | if (addr & 1) { | 
|  | addr &= ~1; | 
|  | data <<= 8; | 
 | } | } | 
 |  | egc_write_w(pset->base.addr + addr, data); | 
 | } | } | 
 |  |  | 
| static const GDCPSFN psettbl[] = { |  | 
| _replace,       _complemnt,     _clear,         _set, | static const GDCPFN psettbl[4][2] = { | 
| _replace,       _complemnt,     _clear,         _set, | {_replace0,     _replace1}, | 
| _tdw,           _tdw,           _nop,           _tdw, | {_nop,          _complemnt}, | 
| _rmw,           _rmw,           _nop,           _rmw}; | {_nop,          _clear}, | 
|  | {_nop,          _set}}; | 
 |  |  | 
 |  |  | 
 | // ---- | // ---- | 
 |  |  | 
| void MEMCALL gdcpset_prepare(GDCPSET pset, UINT32 csrw, UINT16 pat, BYTE op) { | void MEMCALL gdcpset_prepare(GDCPSET pset, UINT32 csrw, REG16 pat, REG8 op) { | 
 |  |  | 
| BYTE    *base; | UINT8   *base; | 
| BYTE    update; | UINT8   update; | 
 |  |  | 
| base = mem; | if (vramop.operate & VOP_EGCBIT) { | 
| if (!gdcs.access) { | pset->func[0] = _nop; | 
| update = 1; | pset->func[1] = withegc; | 
|  | pset->base.addr = gdcplaneseg[(csrw >> 14) & 3]; | 
 | } | } | 
 | else { | else { | 
| base += VRAM_STEP; | base = mem; | 
| update = 2; | if (!gdcs.access) { | 
| } | update = 1; | 
| op &= 3; | } | 
| if (!(grcg.gdcwithgrcg & 0x8)) { | else { | 
| base += vramplaneseg[(csrw >> 14) & 3]; | base += VRAM_STEP; | 
| } | update = 2; | 
| else { | } | 
| op += grcg.gdcwithgrcg; | op &= 3; | 
|  | if (!(grcg.gdcwithgrcg & 0x8)) { | 
|  | pset->func[0] = psettbl[op][0]; | 
|  | pset->func[1] = psettbl[op][1]; | 
|  | pset->base.ptr = base + gdcplaneseg[(csrw >> 14) & 3]; | 
|  | } | 
|  | else { | 
|  | pset->func[0] = _nop; | 
|  | pset->func[1] = (grcg.gdcwithgrcg & 0x4)?withrmw:withtdw; | 
|  | pset->base.ptr = base; | 
|  | } | 
|  | gdcs.grphdisp |= update; | 
|  | pset->update.b[0] = update; | 
|  | pset->update.b[1] = update; | 
 | } | } | 
 | gdcs.grphdisp |= update; |  | 
 | pset->func = psettbl[op]; |  | 
 | pset->base = base; |  | 
 | pset->pattern = pat; | pset->pattern = pat; | 
 | pset->update = update; |  | 
 | pset->x = (UINT16)((((csrw & 0x3fff) % 40) << 4) + ((csrw >> 20) & 0x0f)); | pset->x = (UINT16)((((csrw & 0x3fff) % 40) << 4) + ((csrw >> 20) & 0x0f)); | 
 | pset->y = (UINT16)((csrw & 0x3fff) / 40); | pset->y = (UINT16)((csrw & 0x3fff) / 40); | 
 | pset->dots = 0; | pset->dots = 0; | 
 | } | } | 
 |  |  | 
| void MEMCALL gdcpset(GDCPSET pset, UINT16 x, UINT16 y) { | void MEMCALL gdcpset(GDCPSET pset, REG16 x, REG16 y) { | 
 |  |  | 
 |  | UINT    dot; | 
 |  |  | 
 |  | dot = pset->pattern & 1; | 
 |  | pset->pattern = (pset->pattern >> 1) + (dot << 15); | 
 | pset->dots++; | pset->dots++; | 
 |  | x = LOW16(x); | 
 |  | y = LOW16(y); | 
 | if (y > 409) { | if (y > 409) { | 
| goto nopset; | return; | 
 | } | } | 
 | else if (y == 409) { | else if (y == 409) { | 
 | if (x >= 384) { | if (x >= 384) { | 
| goto nopset; | return; | 
 | } | } | 
 | } | } | 
 | else { | else { | 
 | if (x >= 640) { | if (x >= 640) { | 
| goto nopset; | return; | 
 | } | } | 
 | } | } | 
| (*pset->func)(pset, (y * 80) + (x >> 3), x & 7); | (*pset->func[dot])(pset, (y * 80) + (x >> 3), x & 7); | 
| return; |  | 
|  |  | 
| nopset: |  | 
| pset->pattern = (pset->pattern << 1) + (pset->pattern >> 15); |  | 
 | } | } | 
 |  |  |