-/*\r
- Skelton for retropc emulator\r
-\r
- Origin : MAME HD63484\r
- Author : Takeda.Toshiya\r
- Date : 2009.02.09 -\r
-\r
- [ HD63484 ]\r
-*/\r
-\r
-#include "hd63484.h"\r
-\r
-#define ADDR_MASK (vram_size - 1)\r
-#define CCR regs[0x02 >> 1]\r
-#define MWR1 regs[0xca >> 1]\r
-\r
-static const int instruction_length[64] =\r
-{\r
- 0, 3, 2, 1,\r
- 0, 0,-1, 2,\r
- 0, 3, 3, 3,\r
- 0, 0, 0, 0,\r
- 0, 1, 2, 2,\r
- 0, 0, 4, 4,\r
- 5, 5, 5, 5,\r
- 5, 5, 5, 5,\r
- 3, 3, 3, 3,\r
- 3, 3,-2,-2,\r
- -2,-2, 2, 4,\r
- 5, 5, 7, 7,\r
- 3, 3, 1, 1,\r
- 2, 2, 2, 2,\r
- 5, 5, 5, 5,\r
- 5, 5, 5, 5\r
-};\r
-\r
-void HD63484::initialize()\r
-{\r
- register_vline_event(this);\r
-}\r
-\r
-void HD63484::reset()\r
-{\r
- ch = fifo_ptr = 0;\r
-}\r
-\r
-void HD63484::write_io8(uint32 addr, uint32 data)\r
-{\r
- switch(addr & 3) {\r
- case 0:\r
- write_io16(0, data);\r
- break;\r
- }\r
-}\r
-\r
-uint32 HD63484::read_io8(uint32 addr)\r
-{\r
- switch(addr & 3) {\r
- case 0:\r
- return read_io16(0) & 0xff;\r
- case 1:\r
- return read_io16(0) >> 8;\r
- }\r
- return 0xff;\r
-}\r
-\r
-void HD63484::write_io16(uint32 addr, uint32 data)\r
-{\r
- if(addr & 2) {\r
- // data\r
- regs[ch >> 1] = data;\r
- if(ch & 0x80) {\r
- // auto increment\r
- ch = ((ch + 2) & 0x7f) | 0x80;\r
- }\r
- if(ch == 0) {\r
- fifo[fifo_ptr++] = regs[0];\r
- process_cmd();\r
- }\r
- } else {\r
- // register no\r
- ch = data & 0xff;\r
- }\r
-}\r
-\r
-uint32 HD63484::read_io16(uint32 addr)\r
-{\r
- if(addr & 2) {\r
- // data\r
- if(ch == 0x80) {\r
- return vpos;\r
- } else if(ch == 0) {\r
- return readfifo;\r
- } else {\r
- return 0;\r
- }\r
- } else {\r
- // status\r
- return 0xff22 | (fifo_ptr ? 0 : 1) | (rand() & 4); // write FIFO ready + command end + (read FIFO ready or read FIFO not ready)\r
- }\r
-}\r
-\r
-void HD63484::event_vline(int v, int clock)\r
-{\r
- vpos = v;\r
-}\r
-\r
-void HD63484::process_cmd()\r
-{\r
- int len = instruction_length[fifo[0] >> 10];\r
- \r
- if(len == -1) {\r
- if(fifo_ptr < 2) {\r
- return;\r
- }\r
- len = fifo[1] + 2;\r
- } else if(len == -2) {\r
- if(fifo_ptr < 2) {\r
- return;\r
- }\r
- len = 2 * fifo[1] + 2;\r
- }\r
- if(fifo_ptr >= len) {\r
- if(fifo[0] == 0x400) {\r
- // ORG\r
- org = ((fifo[1] & 0xff) << 12) | ((fifo[2] & 0xfff0) >> 4);\r
- org_dpd = fifo[2] & 0xf;\r
- } else if((fifo[0] & 0xffe0) == 0x800) {\r
- // WPR\r
- if(fifo[0] == 0x800) {\r
- cl0 = fifo[1];\r
- } else if(fifo[0] == 0x801) {\r
- cl1 = fifo[1];\r
- } else if(fifo[0] == 0x802) {\r
- ccmp = fifo[1];\r
- } else if(fifo[0] == 0x803) {\r
- edg = fifo[1];\r
- } else if(fifo[0] == 0x804) {\r
- mask = fifo[1];\r
- } else if(fifo[0] == 0x805) {\r
- ppy = (fifo[1] & 0xf000) >> 12;\r
- pzcy = (fifo[1] & 0x0f00) >> 8;\r
- ppx = (fifo[1] & 0x00f0) >> 4;\r
- pzcx = (fifo[1] & 0x000f) >> 0;\r
- } else if(fifo[0] == 0x806) {\r
- psy = (fifo[1] & 0xf000) >> 12;\r
- psx = (fifo[1] & 0x00f0) >> 4;\r
- } else if(fifo[0] == 0x807) {\r
- pey = (fifo[1] & 0xf000) >> 12;\r
- pzy = (fifo[1] & 0x0f00) >> 8;\r
- pex = (fifo[1] & 0x00f0) >> 4;\r
- pzx = (fifo[1] & 0x000f) >> 0;\r
- } else if(fifo[0] == 0x808) {\r
- xmin = fifo[1];\r
- } else if(fifo[0] == 0x809) {\r
- ymin = fifo[1];\r
- } else if(fifo[0] == 0x80a) {\r
- xmax = fifo[1];\r
- } else if(fifo[0] == 0x80b) {\r
- ymax = fifo[1];\r
- } else if(fifo[0] == 0x80c) {\r
- rwp = (rwp & 0xfff) | ((fifo[1] & 0xff) << 12);\r
- rwp_dn = (fifo[1] & 0xc000) >> 14;\r
- } else if(fifo[0] == 0x80d) {\r
- rwp = (rwp & 0xff000) | ((fifo[1] & 0xfff0) >> 4);\r
- } else {\r
- emu->out_debug_log(_T("HD63484: unsupported register\n"));\r
- }\r
- } else if((fifo[0] & 0xfff0) == 0x1800) {\r
- // WPTN\r
- int start = fifo[0] & 0xf;\r
- int n = fifo[1];\r
- for(int i = 0; i < n; i++) {\r
- pattern[start + i] = fifo[2 + i];\r
- }\r
- } else if(fifo[0] == 0x4400) {\r
- // RD\r
- readfifo = vram[rwp];\r
- rwp = (rwp + 1) & ADDR_MASK;\r
- } else if(fifo[0] == 0x4800) {\r
- // WT\r
- vram[rwp] = fifo[1];\r
- rwp = (rwp + 1) & ADDR_MASK;\r
- } else if(fifo[0] == 0x5800) {\r
- // CLR\r
- doclr16(fifo[0], fifo[1], &rwp, fifo[2], fifo[3]);\r
- int fifo2 = (int)fifo[2], fifo3 = (int)fifo[3];\r
- if(fifo2 < 0) fifo2 *= -1;\r
- if(fifo3 < 0) fifo3 *= -1;\r
- rwp += (fifo2 + 1) * (fifo3 + 1);\r
- } else if((fifo[0] & 0xfffc) == 0x5c00) {\r
- // SCLR\r
- doclr16(fifo[0], fifo[1], &rwp, fifo[2], fifo[3]);\r
- int fifo2 = (int)fifo[2], fifo3 = (int)fifo[3];\r
- if(fifo2 < 0) fifo2 *= -1;\r
- if(fifo3 < 0) fifo3 *= -1;\r
- rwp += (fifo2 + 1) * (fifo3 + 1);\r
- } else if((fifo[0] & 0xf0ff) == 0x6000) {\r
- // CPY\r
- docpy16(fifo[0], ((fifo[1] & 0xff) << 12) | ((fifo[2] & 0xfff0) >> 4), &rwp, fifo[3], fifo[4]);\r
- int fifo2 = (int)fifo[2], fifo3 = (int)fifo[3];\r
- if(fifo2 < 0) fifo2 *= -1;\r
- if(fifo3 < 0) fifo3 *= -1;\r
- rwp += (fifo2 + 1) * (fifo3 + 1);\r
- } else if((fifo[0] & 0xf0fc) == 0x7000) {\r
- // SCPY\r
- docpy16(fifo[0], ((fifo[1] & 0xff) << 12) | ((fifo[2] & 0xfff0) >> 4), &rwp, fifo[3], fifo[4]);\r
- int fifo2 = (int)fifo[2], fifo3 = (int)fifo[3];\r
- if(fifo2 < 0) fifo2 *= -1;\r
- if(fifo3 < 0) fifo3 *= -1;\r
- rwp += (fifo2 + 1) * (fifo3 + 1);\r
- } else if(fifo[0] == 0x8000) {\r
- // AMOVE\r
- cpx = fifo[1];\r
- cpy = fifo[2];\r
- } else if(fifo[0] == 0x8400) {\r
- // RMOVE\r
- cpx += (int16)fifo[1];\r
- cpy += (int16)fifo[2];\r
- } else if((fifo[0] & 0xff00) == 0x8800) {\r
- // ALINE\r
- line(cpx, cpy, fifo[1], fifo[2], fifo[0] & 0xff);\r
- cpx = (int16)fifo[1];\r
- cpy = (int16)fifo[2];\r
- } else if((fifo[0] & 0xff00) == 0x8c00) {\r
- // RLINE\r
- line(cpx, cpy, cpx + (int16)fifo[1], cpy + (int16)fifo[2], fifo[0] & 0xff);\r
- cpx += (int16)fifo[1];\r
- cpy += (int16)fifo[2];\r
- } else if((fifo[0] & 0xfff8) == 0x9000) {\r
- // ARCT\r
- line(cpx, cpy, (int16)fifo[1], cpy, fifo[0] & 0xff);\r
- line((int16)fifo[1], cpy, (int16)fifo[1], (int16)fifo[2], fifo[0] & 0xff);\r
- line((int16)fifo[1], (int16)fifo[2], cpx, (int16)fifo[2], fifo[0] & 0xff);\r
- line(cpx, (int16)fifo[2], cpx, cpy, fifo[0] & 0xff);\r
- cpx = (int16)fifo[1];\r
- cpy = (int16)fifo[2];\r
- } else if((fifo[0] & 0xfff8) == 0x9400) {\r
- // RRCT\r
- line(cpx, cpy, cpx + (int16)fifo[1], cpy, fifo[0] & 0xff);\r
- line(cpx + (int16)fifo[1], cpy, cpx + (int16)fifo[1], cpy + (int16)fifo[2], fifo[0] & 0xff);\r
- line(cpx + (int16)fifo[1], cpy + (int16)fifo[2], cpx, cpy + (int16)fifo[2], fifo[0] & 0xff);\r
- line(cpx, cpy + (int16)fifo[2], cpx, cpy, fifo[0] & 0xff);\r
- cpx += (int16)fifo[1];\r
- cpy += (int16)fifo[2];\r
- } else if((fifo[0] & 0xfff8) == 0xa400) {\r
- // RPLG added\r
- int sx = cpx;\r
- int sy = cpy;\r
- for(int nseg = 0; nseg < fifo[1]; nseg++) {\r
- int ex = sx + (int16)fifo[2 + nseg * 2];\r
- int ey = sy + (int16)fifo[2 + nseg * 2 + 1];\r
- line(sx, sy, ex, ey, fifo[0] & 7);\r
- sx = ex;\r
- sy = ey;\r
- }\r
- line(sx, sy, cpx, cpy, fifo[0] & 7);\r
- } else if((fifo[0] & 0xfff8) == 0xc000) {\r
- // AFRCT\r
- int16 pcx = fifo[1], pcy = fifo[2];\r
- int16 ax = pcx - cpx, ay = pcy - cpy;\r
- int16 xx = cpx, yy = cpy;\r
- for(;;) {\r
- for(;;) {\r
- dot(xx, yy, fifo[0] & 7, cl0);\r
- if(ax == 0) {\r
- break;\r
- }\r
- if(ax > 0) {\r
- xx++;\r
- ax--;\r
- } else {\r
- xx--;\r
- ax++;\r
- }\r
- }\r
- ax = pcx - cpx;\r
- if(pcy < cpy) {\r
- yy--;\r
- xx -= ax;\r
- if(ay == 0) {\r
- break;\r
- }\r
- ay++;\r
- } else {\r
- yy++;\r
- xx -= ax;\r
- if(ay == 0) {\r
- break;\r
- }\r
- ay--;\r
- }\r
- }\r
- } else if((fifo[0] & 0xfff8) == 0xc400) {\r
- // RFRCT\r
- line(cpx, cpy, cpx + (int16)fifo[1], cpy, fifo[0] & 0xff);\r
- line(cpx + fifo[1], cpy, cpx + fifo[1], cpy + fifo[2], fifo[0] & 0xff);\r
- line(cpx + fifo[1], cpy + fifo[2], cpx, cpy + fifo[2], fifo[0] & 0xff);\r
- line(cpx, cpy + fifo[2], cpx, cpy, fifo[0] & 0xff);\r
- cpx=cpx + (int16)fifo[1];\r
- cpy=cpy + (int16)fifo[2];\r
- } else if(fifo[0] == 0xc800) {\r
- // PAINT\r
- paint(cpx, cpy, cl0);\r
- } else if((fifo[0] & 0xfff8) == 0xcc00) {\r
- // DOT\r
- dot(cpx, cpy, fifo[0] & 0xff, cl0);\r
- } else if((fifo[0] & 0xf000) == 0xd000) {\r
- // PTN\r
- ptn(fifo[0], psx, psy, pex - psx, pey - psy);\r
- if(!(fifo[0] & 0x800)) {\r
- switch(fifo[0] & 0x700) {\r
- case 0x000:\r
- if(pey - psy > 0) {\r
- cpy += pey - psy;\r
- } else {\r
- cpy -= pey - psy;\r
- }\r
- break;\r
- case 0x100:\r
- // missing\r
- break;\r
- case 0x200:\r
- if(pey - psy > 0) {\r
- cpx += pey - psy;\r
- } else {\r
- cpx -= pey - psy;\r
- }\r
- break;\r
- case 0x300:\r
- // missing\r
- break;\r
- case 0x400:\r
- if(pey - psy > 0) {\r
- cpy -= pey - psy;\r
- } else {\r
- cpy += pey - psy;\r
- }\r
- break;\r
- case 0x500:\r
- // missing\r
- break;\r
- case 0x600:\r
- if(pey - psy > 0) {\r
- cpx -= pey - psy;\r
- } else {\r
- cpx += pey - psy;\r
- }\r
- break;\r
- case 0x700:\r
- // missing\r
- break;\r
- }\r
- } else {\r
- // missing\r
- }\r
- } else if((fifo[0] & 0xf018) == 0xe000) {\r
- // AGCPY\r
- agcpy(fifo[0], (int16)fifo[1], (int16)fifo[2], cpx, cpy, fifo[3], fifo[4]);\r
- switch(fifo[0] & 0x700) {\r
- case 0x000:\r
- if(fifo[4] > 0) {\r
- cpy += fifo[4];\r
- } else {\r
- cpy -= fifo[4];\r
- }\r
- break;\r
- case 0x100:\r
- if(fifo[4] > 0) {\r
- cpy -= fifo[4];\r
- } else {\r
- cpy += fifo[4];\r
- }\r
- break;\r
- case 0x200:\r
- if(fifo[4] > 0) {\r
- cpy += fifo[4];\r
- } else {\r
- cpy -= fifo[4];\r
- }\r
- break;\r
- case 0x300:\r
- if(fifo[4] > 0) {\r
- cpy -= fifo[4];\r
- } else {\r
- cpy += fifo[4];\r
- }\r
- break;\r
- case 0x400:\r
- if(fifo[3] > 0) {\r
- cpx += fifo[3];\r
- } else {\r
- cpx -= fifo[3];\r
- }\r
- break;\r
- case 0x500:\r
- if(fifo[3] > 0) {\r
- cpx += fifo[3];\r
- } else {\r
- cpx -= fifo[3];\r
- }\r
- break;\r
- case 0x600:\r
- if(fifo[3] > 0) {\r
- cpx -= fifo[3];\r
- } else {\r
- cpx += fifo[3];\r
- }\r
- break;\r
- case 0x700:\r
- if(fifo[3] > 0) {\r
- cpx -= fifo[3];\r
- } else {\r
- cpx += fifo[3];\r
- }\r
- break;\r
- }\r
- } else {\r
- emu->out_debug_log(_T("unsupported command\n"));\r
- }\r
- fifo_ptr = 0;\r
- }\r
-}\r
-\r
-void HD63484::doclr16(int opcode, uint16 fill, int *dst, int _ax, int _ay)\r
-{\r
- int ax = _ax, ay = _ay;\r
- \r
- for(;;) {\r
- for(;;) {\r
- switch(opcode & 3) {\r
- case 0:\r
- vram[*dst & ADDR_MASK] = fill;\r
- break;\r
- case 1:\r
- vram[*dst & ADDR_MASK] |= fill;\r
- break;\r
- case 2:\r
- vram[*dst & ADDR_MASK] &= fill;\r
- break;\r
- case 3:\r
- vram[*dst & ADDR_MASK] ^= fill;\r
- break;\r
- }\r
- if(ax == 0) {\r
- break;\r
- }\r
- if(ax > 0) {\r
- *dst = (*dst + 1) & ADDR_MASK;\r
- ax--;\r
- } else {\r
- *dst = (*dst - 1) & ADDR_MASK;\r
- ax++;\r
- }\r
- }\r
- ax = _ax;\r
- if(_ay < 0) {\r
- *dst = (*dst + (MWR1 & 0xfff) - ax) & ADDR_MASK;\r
- if(ay == 0) {\r
- break;\r
- }\r
- ay++;\r
- } else {\r
- *dst = (*dst - (MWR1 & 0xfff) - ax) & ADDR_MASK;\r
- if(ay == 0) {\r
- break;\r
- }\r
- ay--;\r
- }\r
- }\r
-}\r
-\r
-void HD63484::docpy16(int opcode, int src, int *dst, int _ax, int _ay)\r
-{\r
- int dstep1, dstep2;\r
- int ax = _ax, ay = _ay;\r
- \r
- switch(opcode & 0x700) {\r
- case 0x000: dstep1 = 1; dstep2 = -1 * (MWR1 & 0xfff) - ax * dstep1; break;\r
- case 0x100: dstep1 = 1; dstep2 = (MWR1 & 0xfff) - ax * dstep1; break;\r
- case 0x200: dstep1 = -1; dstep2 = -1 * (MWR1 & 0xfff) + ax * dstep1; break;\r
- case 0x300: dstep1 = -1; dstep2 = (MWR1 & 0xfff) + ax * dstep1; break;\r
- case 0x400: dstep1 = -1 * (MWR1 & 0xfff); dstep2 = 1 - ay * dstep1; break;\r
- case 0x500: dstep1 = (MWR1 & 0xfff); dstep2 = 1 - ay * dstep1; break;\r
- case 0x600: dstep1 = -1 * (MWR1 & 0xfff); dstep2 = -1 + ay * dstep1; break;\r
- case 0x700: dstep1 = (MWR1 & 0xfff); dstep2 = -1 + ay * dstep1; break;\r
- }\r
- for(;;) {\r
- for(;;) {\r
- switch(opcode & 7) {\r
- case 0:\r
- vram[*dst] = vram[src];\r
- break;\r
- case 1:\r
- vram[*dst] |= vram[src];\r
- break;\r
- case 2:\r
- vram[*dst] &= vram[src];\r
- break;\r
- case 3:\r
- vram[*dst] ^= vram[src];\r
- break;\r
- case 4:\r
- if(vram[*dst] == (ccmp & 0xff)) {\r
- vram[*dst] = vram[src];\r
- }\r
- break;\r
- case 5:\r
- if(vram[*dst] != (ccmp & 0xff)) {\r
- vram[*dst] = vram[src];\r
- }\r
- break;\r
- case 6:\r
- if(vram[*dst] < vram[src]) {\r
- vram[*dst] = vram[src];\r
- }\r
- break;\r
- case 7:\r
- if(vram[*dst] > vram[src]) {\r
- vram[*dst] = vram[src];\r
- }\r
- break;\r
- }\r
- if(opcode & 0x800) {\r
- if(ay == 0) {\r
- break;\r
- }\r
- if(_ay > 0) {\r
- src = (src - (MWR1 & 0xfff)) & ADDR_MASK;\r
- *dst = (*dst + dstep1) & ADDR_MASK;\r
- ay--;\r
- } else {\r
- src = (src + (MWR1 & 0xfff)) & ADDR_MASK;\r
- *dst = (*dst + dstep1) & ADDR_MASK;\r
- ay++;\r
- }\r
- } else {\r
- if(ax == 0) {\r
- break;\r
- }\r
- if(ax > 0) {\r
- src = (src + 1) & ADDR_MASK;\r
- *dst = (*dst + dstep1) & ADDR_MASK;\r
- ax--;\r
- } else {\r
- src = (src - 1) & ADDR_MASK;\r
- *dst = (*dst + dstep1) & ADDR_MASK;\r
- ax++;\r
- }\r
- }\r
- }\r
- if(opcode & 0x800) {\r
- ay = _ay;\r
- if(_ax < 0) {\r
- src = (src - 1 + ay * (MWR1 & 0xfff)) & ADDR_MASK;\r
- *dst = (*dst + dstep2) & ADDR_MASK;\r
- if(ax == 0) {\r
- break;\r
- }\r
- ax++;\r
- } else {\r
- src = (src + 1 - ay * (MWR1 & 0xfff)) & ADDR_MASK;\r
- *dst = (*dst + dstep2) & ADDR_MASK;\r
- if(ax == 0) {\r
- break;\r
- }\r
- ax--;\r
- }\r
- } else {\r
- ax = _ax;\r
- if(_ay < 0) {\r
- src = (src + (MWR1 & 0xfff) - ax) & ADDR_MASK;\r
- *dst = (*dst + dstep2) & ADDR_MASK;\r
- if(ay == 0) {\r
- break;\r
- }\r
- ay++;\r
- } else {\r
- src = (src - (MWR1 & 0xfff) - ax) & ADDR_MASK;\r
- *dst = (*dst + dstep2) & ADDR_MASK;\r
- if(ay == 0) {\r
- break;\r
- }\r
- ay--;\r
- }\r
- }\r
- }\r
-}\r
-\r
-int HD63484::org_first_pixel(int _org_dpd)\r
-{\r
- int gbm = (CCR & 0x700) >> 8;\r
- \r
- switch(gbm) {\r
- case 0:\r
- return (_org_dpd & 0xf);\r
- case 1:\r
- return (_org_dpd & 0xf) >> 1;\r
- case 2:\r
- return (_org_dpd & 0xf) >> 2;\r
- case 3:\r
- return (_org_dpd & 0xf) >> 3;\r
- case 4:\r
- return 0;\r
- }\r
- emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));\r
- return 0;\r
-}\r
-\r
-void HD63484::dot(int x, int y, int opm, uint16 color)\r
-{\r
- int dst, x_int, x_mod, bpp;\r
- uint16 color_shifted, bitmask, bitmask_shifted;\r
- \r
- x += org_first_pixel(org_dpd);\r
- \r
- switch((CCR & 0x700) >> 8) {\r
- case 0:\r
- bpp = 1;\r
- bitmask = 0x0001;\r
- break;\r
- case 1:\r
- bpp = 2;\r
- bitmask = 0x0003;\r
- break;\r
- case 2:\r
- bpp = 4;\r
- bitmask = 0x000f;\r
- break;\r
- case 3:\r
- bpp = 8;\r
- bitmask = 0x00ff;\r
- break;\r
- case 4:\r
- bpp = 16;\r
- bitmask = 0xffff;\r
- break;\r
- default:\r
- emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));\r
- bpp = 0;\r
- bitmask = 0x0000;\r
- }\r
- if(x >= 0) {\r
- x_int = x / (16 / bpp);\r
- x_mod = x % (16 / bpp);\r
- } else {\r
- x_int = x / (16 / bpp);\r
- x_mod = -1 * (x % (16 / bpp));\r
- if(x_mod) {\r
- x_int--;\r
- x_mod = (16 / bpp) - x_mod;\r
- }\r
- }\r
- \r
- color &= bitmask;\r
- bitmask_shifted = bitmask << (x_mod * bpp);\r
- color_shifted = color << (x_mod * bpp);\r
- dst = (org + x_int - y * (MWR1 & 0xfff)) & ADDR_MASK;\r
- \r
- switch(opm) {\r
- case 0:\r
- vram[dst] = (vram[dst] & ~bitmask_shifted) | color_shifted;\r
- break;\r
- case 1:\r
- vram[dst] = vram[dst] | color_shifted;\r
- break;\r
- case 2:\r
- vram[dst] = vram[dst] & ((vram[dst] & ~bitmask_shifted) | color_shifted);\r
- break;\r
- case 3:\r
- vram[dst] = vram[dst] ^ color_shifted;\r
- break;\r
- case 4:\r
- if(get_pixel(x, y) == (ccmp & bitmask)) {\r
- vram[dst] = (vram[dst] & ~bitmask_shifted) | color_shifted;\r
- }\r
- break;\r
- case 5:\r
- if(get_pixel(x, y) != (ccmp & bitmask)) {\r
- vram[dst] = (vram[dst] & ~bitmask_shifted) | color_shifted;\r
- }\r
- break;\r
- case 6:\r
- if(get_pixel(x, y) < (cl0 & bitmask)) {\r
- vram[dst] = (vram[dst] & ~bitmask_shifted) | color_shifted;\r
- }\r
- break;\r
- case 7:\r
- if(get_pixel(x, y) > (cl0 & bitmask)) {\r
- vram[dst] = (vram[dst] & ~bitmask_shifted) | color_shifted;\r
- }\r
- break;\r
- }\r
-}\r
-\r
-int HD63484::get_pixel(int x, int y)\r
-{\r
- int dst, x_int, x_mod, bpp;\r
- uint16 bitmask, bitmask_shifted;\r
- \r
- switch((CCR & 0x700) >> 8) {\r
- case 0:\r
- bpp = 1;\r
- bitmask = 0x0001;\r
- break;\r
- case 1:\r
- bpp = 2;\r
- bitmask = 0x0003;\r
- break;\r
- case 2:\r
- bpp = 4;\r
- bitmask = 0x000f;\r
- break;\r
- case 3:\r
- bpp = 8;\r
- bitmask = 0x00ff;\r
- break;\r
- case 4:\r
- bpp = 16;\r
- bitmask = 0xffff;\r
- break;\r
- default:\r
- emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));\r
- bpp = 0;\r
- bitmask = 0x0000;\r
- }\r
- if(x >= 0) {\r
- x_int = x / (16 / bpp);\r
- x_mod = x % (16 / bpp);\r
- } else {\r
- x_int = x / (16 / bpp);\r
- x_mod = -1 * (x % (16 / bpp));\r
- if(x_mod) {\r
- x_int--;\r
- x_mod = (16 / bpp) - x_mod;\r
- }\r
- }\r
- bitmask_shifted = bitmask << (x_mod * bpp);\r
- dst = (org + x_int - y * (MWR1 & 0xfff)) & ADDR_MASK;\r
- \r
- return ((vram[dst] & bitmask_shifted) >> (x_mod * bpp));\r
-}\r
-\r
-int HD63484::get_pixel_ptn(int x, int y)\r
-{\r
- int dst, x_int, x_mod, bpp;\r
- uint16 bitmask, bitmask_shifted;\r
- \r
- bpp = 1;\r
- bitmask = 1;\r
- \r
- if(x >= 0) {\r
- x_int = x / (16 / bpp);\r
- x_mod = x % (16 / bpp);\r
- } else {\r
- x_int = x / (16 / bpp);\r
- x_mod = -1 * (x % (16 / bpp));\r
- if(x_mod) {\r
- x_int--;\r
- x_mod = (16 / bpp) - x_mod;\r
- }\r
- }\r
- bitmask_shifted = bitmask << (x_mod * bpp);\r
- dst = (x_int + y * 1);\r
- \r
- if((pattern[dst] & bitmask_shifted) >> (x_mod * bpp)) {\r
- return 1;\r
- } else {\r
- return 0;\r
- }\r
-}\r
-\r
-void HD63484::agcpy(int opcode, int src_x, int src_y, int dst_x, int dst_y, int16 _ax, int16 _ay)\r
-{\r
- int dst_step1_x, dst_step1_y, dst_step2_x, dst_step2_y;\r
- int src_step1_x, src_step1_y, src_step2_x, src_step2_y;\r
- int ax = _ax;\r
- int ay = _ay;\r
- int ax_neg = (_ax >= 0) ? 1 : -1;\r
- int ay_neg = (_ay >= 0) ? 1 : -1;\r
- int xxs = src_x;\r
- int yys = src_y;\r
- int xxd = dst_x;\r
- int yyd = dst_y;\r
- \r
- if(opcode & 0x800) {\r
- switch(opcode & 0x700) {\r
- case 0x000: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ay_neg * ay; dst_step2_y = 1; break;\r
- case 0x100: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ay_neg * ay; dst_step2_y = -1; break;\r
- case 0x200: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ay_neg * ay; dst_step2_y = 1; break;\r
- case 0x300: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ay_neg * ay; dst_step2_y = -1; break;\r
- case 0x400: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = 1; dst_step2_y = -ay_neg * ay; break;\r
- case 0x500: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = 1; dst_step2_y = ay_neg * ay; break;\r
- case 0x600: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = -1; dst_step2_y = -ay_neg * ay; break;\r
- case 0x700: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = -1; dst_step2_y = ay_neg * ay; break;\r
- }\r
- src_step1_x = 0;\r
- src_step1_y = (_ay >= 0) ? 1 : -1;\r
- src_step2_x = (_ax >= 0) ? 1 : -1;\r
- src_step2_y = -ay;\r
- } else {\r
- switch(opcode & 0x700) {\r
- case 0x000: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ax_neg * ax; dst_step2_y = 1; break;\r
- case 0x100: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ax_neg * ax; dst_step2_y = -1; break;\r
- case 0x200: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ax_neg * ax; dst_step2_y = 1; break;\r
- case 0x300: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ax_neg * ax; dst_step2_y = -1; break;\r
- case 0x400: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = 1; dst_step2_y = ax_neg * ax; break;\r
- case 0x500: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = 1; dst_step2_y = -ax_neg * ax; break;\r
- case 0x600: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = -1; dst_step2_y = ax_neg * ax; break;\r
- case 0x700: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = -1; dst_step2_y = -ax_neg * ax; break;\r
- }\r
- src_step1_x = (_ax >= 0) ? 1 : -1;\r
- src_step1_y = 0;\r
- src_step2_x = -ax;\r
- src_step2_y = (_ay >= 0) ? 1 : -1;\r
- }\r
- for(;;) {\r
- for(;;) {\r
- dot(xxd, yyd, opcode & 7, get_pixel(xxs, yys));\r
- if(opcode & 0x800) {\r
- if(ay == 0) {\r
- break;\r
- }\r
- if(_ay > 0) {\r
- xxs += src_step1_x;\r
- yys += src_step1_y;\r
- xxd += dst_step1_x;\r
- yyd += dst_step1_y;\r
- ay--;\r
- } else {\r
- xxs += src_step1_x;\r
- yys += src_step1_y;\r
- xxd += dst_step1_x;\r
- yyd += dst_step1_y;\r
- ay++;\r
- }\r
- } else {\r
- if(ax == 0) {\r
- break;\r
- }\r
- if(ax > 0) {\r
- xxs += src_step1_x;\r
- yys += src_step1_y;\r
- xxd += dst_step1_x;\r
- yyd += dst_step1_y;\r
- ax--;\r
- } else {\r
- xxs += src_step1_x;\r
- yys += src_step1_y;\r
- xxd += dst_step1_x;\r
- yyd += dst_step1_y;\r
- ax++;\r
- }\r
- }\r
- }\r
- if(opcode & 0x800) {\r
- ay = _ay;\r
- if(_ax < 0) {\r
- xxs += src_step2_x;\r
- yys += src_step2_y;\r
- xxd += dst_step2_x;\r
- yyd += dst_step2_y;\r
- if(ax == 0) {\r
- break;\r
- }\r
- ax++;\r
- } else {\r
- xxs += src_step2_x;\r
- yys += src_step2_y;\r
- xxd += dst_step2_x;\r
- yyd += dst_step2_y;\r
- if(ax == 0) {\r
- break;\r
- }\r
- ax--;\r
- }\r
- } else {\r
- ax = _ax;\r
- if(_ay < 0) {\r
- xxs += src_step2_x;\r
- yys += src_step2_y;\r
- xxd += dst_step2_x;\r
- yyd += dst_step2_y;\r
- if(ay == 0) {\r
- break;\r
- }\r
- ay++;\r
- } else {\r
- xxs += src_step2_x;\r
- yys += src_step2_y;\r
- xxd += dst_step2_x;\r
- yyd += dst_step2_y;\r
- if(ay == 0) {\r
- break;\r
- }\r
- ay--;\r
- }\r
- }\r
- }\r
-}\r
-\r
-void HD63484::ptn(int opcode, int src_x, int src_y, int16 _ax, int16 _ay)\r
-{\r
- int dst_step1_x = 0, dst_step1_y = 0, dst_step2_x = 0, dst_step2_y = 0;\r
- int src_step1_x = 1, src_step1_y = 0, src_step2_x = -_ax, src_step2_y = 1;\r
- int ax = _ax;\r
- int ay = _ay;\r
- int ax_neg = (_ax >= 0) ? 1 : -1;\r
- int ay_neg = (_ay >= 0) ? 1 : -1;\r
- int xxs = src_x;\r
- int yys = src_y;\r
- int xxd = cpx;\r
- int yyd = cpy;\r
- int getpixel;\r
- \r
- if(opcode & 0x800) {\r
- emu->out_debug_log(_T("HD63484 ptn not supported\n"));\r
- } else {\r
- switch(opcode & 0x700) {\r
- case 0x000: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ax_neg * ax; dst_step2_y = 1; break;\r
- case 0x100: emu->out_debug_log(_T("HD63484 ptn not supported\n")); break;\r
- case 0x200: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = -1; dst_step2_y = -ax_neg * ax; break;\r
- case 0x300: emu->out_debug_log(_T("HD63484 ptn not supported\n")); break;\r
- case 0x400: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ax_neg * ax; dst_step2_y = -1; break;\r
- case 0x500: emu->out_debug_log(_T("HD63484 ptn not supported\n")); break;\r
- case 0x600: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = 1; dst_step2_y = ax_neg * ax; break;\r
- case 0x700: emu->out_debug_log(_T("HD63484 ptn not supported\n")); break;\r
- }\r
- }\r
- for(;;) {\r
- for(;;) {\r
- getpixel = get_pixel_ptn(xxs, yys);\r
- switch((opcode >> 3) & 3) {\r
- case 0:\r
- if(getpixel) {\r
- dot(xxd, yyd, opcode & 7, cl1);\r
- } else {\r
- dot(xxd, yyd, opcode & 7, cl0);\r
- }\r
- break;\r
- case 1:\r
- if(getpixel) {\r
- dot(xxd, yyd, opcode & 7, cl1);\r
- }\r
- break;\r
- case 2:\r
- if(getpixel == 0) {\r
- dot(xxd, yyd, opcode & 7, cl0);\r
- }\r
- break;\r
- case 3:\r
- emu->out_debug_log(_T("HD63484 ptn not supported\n"));\r
- break;\r
- }\r
- if(opcode & 0x800) {\r
- if(ay == 0) {\r
- break;\r
- }\r
- if(_ay > 0) {\r
- xxs += src_step1_x;\r
- yys += src_step1_y;\r
- xxd += dst_step1_x;\r
- yyd += dst_step1_y;\r
- ay--;\r
- } else {\r
- xxs += src_step1_x;\r
- yys += src_step1_y;\r
- xxd += dst_step1_x;\r
- yyd += dst_step1_y;\r
- ay++;\r
- }\r
- } else {\r
- if(ax == 0) {\r
- break;\r
- }\r
- if(ax > 0) {\r
- xxs += src_step1_x;\r
- yys += src_step1_y;\r
- xxd += dst_step1_x;\r
- yyd += dst_step1_y;\r
- ax--;\r
- } else {\r
- xxs += src_step1_x;\r
- yys += src_step1_y;\r
- xxd += dst_step1_x;\r
- yyd += dst_step1_y;\r
- ax++;\r
- }\r
- }\r
- }\r
- if(opcode & 0x800) {\r
- ay = _ay;\r
- if(_ax < 0) {\r
- xxs += src_step2_x;\r
- yys += src_step2_y;\r
- xxd += dst_step2_x;\r
- yyd += dst_step2_y;\r
- if(ax == 0) break;\r
- ax++;\r
- } else {\r
- xxs += src_step2_x;\r
- yys += src_step2_y;\r
- xxd += dst_step2_x;\r
- yyd += dst_step2_y;\r
- if(ax == 0) break;\r
- ax--;\r
- }\r
- } else {\r
- ax = _ax;\r
- if(_ay < 0) {\r
- xxs += src_step2_x;\r
- yys += src_step2_y;\r
- xxd += dst_step2_x;\r
- yyd += dst_step2_y;\r
- if(ay == 0) break;\r
- ay++;\r
- } else {\r
- xxs += src_step2_x;\r
- yys += src_step2_y;\r
- xxd += dst_step2_x;\r
- yyd += dst_step2_y;\r
- if(ay == 0) break;\r
- ay--;\r
- }\r
- }\r
- }\r
-}\r
-\r
-void HD63484::line(int16 sx, int16 sy, int16 ex, int16 ey, int16 col)\r
-{\r
- int cpx_t = sx;\r
- int cpy_t = sy;\r
- int16 ax = ex - sx;\r
- int16 ay = ey - sy;\r
- \r
- if(abs(ax) >= abs(ay)) {\r
- while(ax) {\r
- dot(cpx_t, cpy_t, col & 7, cl0);\r
- if(ax > 0) {\r
- cpx_t++;\r
- ax--;\r
- } else {\r
- cpx_t--;\r
- ax++;\r
- }\r
- cpy_t = sy + ay * (cpx_t - sx) / (ex - sx);\r
- }\r
- } else {\r
- while(ay) {\r
- dot(cpx_t, cpy_t, col & 7, cl0);\r
- if(ay > 0) {\r
- cpy_t++;\r
- ay--;\r
- } else {\r
- cpy_t--;\r
- ay++;\r
- }\r
- cpx_t = sx + ax * (cpy_t - sy) / (ey - sy);\r
- }\r
- }\r
-}\r
-\r
-void HD63484::paint(int sx, int sy, int col)\r
-{\r
- int getpixel;\r
- dot(sx, sy, 0, col);\r
- \r
- getpixel = get_pixel(sx + 1, sy);\r
- switch((CCR & 0x700) >> 8) {\r
- case 0:\r
- break;\r
- case 1:\r
- break;\r
- case 2:\r
- getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0);\r
- break;\r
- case 3:\r
- getpixel = (getpixel << 8) | (getpixel << 0);\r
- break;\r
- case 4:\r
- break;\r
- default:\r
- emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));\r
- }\r
- if((getpixel != col) && (getpixel != edg)) {\r
- sx++;\r
- paint(sx, sy, col);\r
- sx--;\r
- }\r
- \r
- getpixel = get_pixel(sx - 1, sy);\r
- switch((CCR & 0x700) >> 8) {\r
- case 0:\r
- break;\r
- case 1:\r
- break;\r
- case 2:\r
- getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0);\r
- break;\r
- case 3:\r
- getpixel = (getpixel << 8) | (getpixel << 0);\r
- break;\r
- case 4:\r
- break;\r
- default:\r
- emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));\r
- }\r
- if((getpixel != col) && (getpixel != edg)) {\r
- sx--;\r
- paint(sx, sy, col);\r
- sx++;\r
- }\r
- \r
- getpixel = get_pixel(sx, sy + 1);\r
- switch((CCR & 0x700) >> 8) {\r
- case 0:\r
- break;\r
- case 1:\r
- break;\r
- case 2:\r
- getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0);\r
- break;\r
- case 3:\r
- getpixel = (getpixel << 8) | (getpixel << 0);\r
- break;\r
- case 4:\r
- break;\r
- default:\r
- emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));\r
- }\r
- if((getpixel != col) && (getpixel != edg)) {\r
- sy++;\r
- paint(sx, sy, col);\r
- sy--;\r
- }\r
- \r
- getpixel = get_pixel(sx, sy - 1);\r
- switch((CCR & 0x700) >> 8) {\r
- case 0:\r
- break;\r
- case 1:\r
- break;\r
- case 2:\r
- getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0);\r
- break;\r
- case 3:\r
- getpixel = (getpixel << 8) | (getpixel << 0);\r
- break;\r
- case 4:\r
- break;\r
- default:\r
- emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));\r
- }\r
- if((getpixel != col) && (getpixel != edg)) {\r
- sy--;\r
- paint(sx, sy, col);\r
- sy++;\r
- }\r
-}\r
-\r
+/*
+ Skelton for retropc emulator
+
+ Origin : MAME HD63484
+ Author : Takeda.Toshiya
+ Date : 2009.02.09 -
+
+ [ HD63484 ]
+*/
+
+#include "hd63484.h"
+
+#define ADDR_MASK (vram_size - 1)
+#define CCR regs[0x02 >> 1]
+#define MWR1 regs[0xca >> 1]
+
+static const int instruction_length[64] =
+{
+ 0, 3, 2, 1,
+ 0, 0,-1, 2,
+ 0, 3, 3, 3,
+ 0, 0, 0, 0,
+ 0, 1, 2, 2,
+ 0, 0, 4, 4,
+ 5, 5, 5, 5,
+ 5, 5, 5, 5,
+ 3, 3, 3, 3,
+ 3, 3,-2,-2,
+ -2,-2, 2, 4,
+ 5, 5, 7, 7,
+ 3, 3, 1, 1,
+ 2, 2, 2, 2,
+ 5, 5, 5, 5,
+ 5, 5, 5, 5
+};
+
+void HD63484::initialize()
+{
+ register_vline_event(this);
+}
+
+void HD63484::reset()
+{
+ ch = fifo_ptr = 0;
+}
+
+void HD63484::write_io8(uint32 addr, uint32 data)
+{
+ switch(addr & 3) {
+ case 0:
+ write_io16(0, data);
+ break;
+ }
+}
+
+uint32 HD63484::read_io8(uint32 addr)
+{
+ switch(addr & 3) {
+ case 0:
+ return read_io16(0) & 0xff;
+ case 1:
+ return read_io16(0) >> 8;
+ }
+ return 0xff;
+}
+
+void HD63484::write_io16(uint32 addr, uint32 data)
+{
+ if(addr & 2) {
+ // data
+ regs[ch >> 1] = data;
+ if(ch & 0x80) {
+ // auto increment
+ ch = ((ch + 2) & 0x7f) | 0x80;
+ }
+ if(ch == 0) {
+ fifo[fifo_ptr++] = regs[0];
+ process_cmd();
+ }
+ } else {
+ // register no
+ ch = data & 0xff;
+ }
+}
+
+uint32 HD63484::read_io16(uint32 addr)
+{
+ if(addr & 2) {
+ // data
+ if(ch == 0x80) {
+ return vpos;
+ } else if(ch == 0) {
+ return readfifo;
+ } else {
+ return 0;
+ }
+ } else {
+ // status
+ return 0xff22 | (fifo_ptr ? 0 : 1) | (rand() & 4); // write FIFO ready + command end + (read FIFO ready or read FIFO not ready)
+ }
+}
+
+void HD63484::event_vline(int v, int clock)
+{
+ vpos = v;
+}
+
+void HD63484::process_cmd()
+{
+ int len = instruction_length[fifo[0] >> 10];
+
+ if(len == -1) {
+ if(fifo_ptr < 2) {
+ return;
+ }
+ len = fifo[1] + 2;
+ } else if(len == -2) {
+ if(fifo_ptr < 2) {
+ return;
+ }
+ len = 2 * fifo[1] + 2;
+ }
+ if(fifo_ptr >= len) {
+ if(fifo[0] == 0x400) {
+ // ORG
+ org = ((fifo[1] & 0xff) << 12) | ((fifo[2] & 0xfff0) >> 4);
+ org_dpd = fifo[2] & 0xf;
+ } else if((fifo[0] & 0xffe0) == 0x800) {
+ // WPR
+ if(fifo[0] == 0x800) {
+ cl0 = fifo[1];
+ } else if(fifo[0] == 0x801) {
+ cl1 = fifo[1];
+ } else if(fifo[0] == 0x802) {
+ ccmp = fifo[1];
+ } else if(fifo[0] == 0x803) {
+ edg = fifo[1];
+ } else if(fifo[0] == 0x804) {
+ mask = fifo[1];
+ } else if(fifo[0] == 0x805) {
+ ppy = (fifo[1] & 0xf000) >> 12;
+ pzcy = (fifo[1] & 0x0f00) >> 8;
+ ppx = (fifo[1] & 0x00f0) >> 4;
+ pzcx = (fifo[1] & 0x000f) >> 0;
+ } else if(fifo[0] == 0x806) {
+ psy = (fifo[1] & 0xf000) >> 12;
+ psx = (fifo[1] & 0x00f0) >> 4;
+ } else if(fifo[0] == 0x807) {
+ pey = (fifo[1] & 0xf000) >> 12;
+ pzy = (fifo[1] & 0x0f00) >> 8;
+ pex = (fifo[1] & 0x00f0) >> 4;
+ pzx = (fifo[1] & 0x000f) >> 0;
+ } else if(fifo[0] == 0x808) {
+ xmin = fifo[1];
+ } else if(fifo[0] == 0x809) {
+ ymin = fifo[1];
+ } else if(fifo[0] == 0x80a) {
+ xmax = fifo[1];
+ } else if(fifo[0] == 0x80b) {
+ ymax = fifo[1];
+ } else if(fifo[0] == 0x80c) {
+ rwp = (rwp & 0xfff) | ((fifo[1] & 0xff) << 12);
+ rwp_dn = (fifo[1] & 0xc000) >> 14;
+ } else if(fifo[0] == 0x80d) {
+ rwp = (rwp & 0xff000) | ((fifo[1] & 0xfff0) >> 4);
+ } else {
+ emu->out_debug_log(_T("HD63484: unsupported register\n"));
+ }
+ } else if((fifo[0] & 0xfff0) == 0x1800) {
+ // WPTN
+ int start = fifo[0] & 0xf;
+ int n = fifo[1];
+ for(int i = 0; i < n; i++) {
+ pattern[start + i] = fifo[2 + i];
+ }
+ } else if(fifo[0] == 0x4400) {
+ // RD
+ readfifo = vram[rwp];
+ rwp = (rwp + 1) & ADDR_MASK;
+ } else if(fifo[0] == 0x4800) {
+ // WT
+ vram[rwp] = fifo[1];
+ rwp = (rwp + 1) & ADDR_MASK;
+ } else if(fifo[0] == 0x5800) {
+ // CLR
+ doclr16(fifo[0], fifo[1], &rwp, fifo[2], fifo[3]);
+ int fifo2 = (int)fifo[2], fifo3 = (int)fifo[3];
+ if(fifo2 < 0) fifo2 *= -1;
+ if(fifo3 < 0) fifo3 *= -1;
+ rwp += (fifo2 + 1) * (fifo3 + 1);
+ } else if((fifo[0] & 0xfffc) == 0x5c00) {
+ // SCLR
+ doclr16(fifo[0], fifo[1], &rwp, fifo[2], fifo[3]);
+ int fifo2 = (int)fifo[2], fifo3 = (int)fifo[3];
+ if(fifo2 < 0) fifo2 *= -1;
+ if(fifo3 < 0) fifo3 *= -1;
+ rwp += (fifo2 + 1) * (fifo3 + 1);
+ } else if((fifo[0] & 0xf0ff) == 0x6000) {
+ // CPY
+ docpy16(fifo[0], ((fifo[1] & 0xff) << 12) | ((fifo[2] & 0xfff0) >> 4), &rwp, fifo[3], fifo[4]);
+ int fifo2 = (int)fifo[2], fifo3 = (int)fifo[3];
+ if(fifo2 < 0) fifo2 *= -1;
+ if(fifo3 < 0) fifo3 *= -1;
+ rwp += (fifo2 + 1) * (fifo3 + 1);
+ } else if((fifo[0] & 0xf0fc) == 0x7000) {
+ // SCPY
+ docpy16(fifo[0], ((fifo[1] & 0xff) << 12) | ((fifo[2] & 0xfff0) >> 4), &rwp, fifo[3], fifo[4]);
+ int fifo2 = (int)fifo[2], fifo3 = (int)fifo[3];
+ if(fifo2 < 0) fifo2 *= -1;
+ if(fifo3 < 0) fifo3 *= -1;
+ rwp += (fifo2 + 1) * (fifo3 + 1);
+ } else if(fifo[0] == 0x8000) {
+ // AMOVE
+ cpx = fifo[1];
+ cpy = fifo[2];
+ } else if(fifo[0] == 0x8400) {
+ // RMOVE
+ cpx += (int16)fifo[1];
+ cpy += (int16)fifo[2];
+ } else if((fifo[0] & 0xff00) == 0x8800) {
+ // ALINE
+ line(cpx, cpy, fifo[1], fifo[2], fifo[0] & 0xff);
+ cpx = (int16)fifo[1];
+ cpy = (int16)fifo[2];
+ } else if((fifo[0] & 0xff00) == 0x8c00) {
+ // RLINE
+ line(cpx, cpy, cpx + (int16)fifo[1], cpy + (int16)fifo[2], fifo[0] & 0xff);
+ cpx += (int16)fifo[1];
+ cpy += (int16)fifo[2];
+ } else if((fifo[0] & 0xfff8) == 0x9000) {
+ // ARCT
+ line(cpx, cpy, (int16)fifo[1], cpy, fifo[0] & 0xff);
+ line((int16)fifo[1], cpy, (int16)fifo[1], (int16)fifo[2], fifo[0] & 0xff);
+ line((int16)fifo[1], (int16)fifo[2], cpx, (int16)fifo[2], fifo[0] & 0xff);
+ line(cpx, (int16)fifo[2], cpx, cpy, fifo[0] & 0xff);
+ cpx = (int16)fifo[1];
+ cpy = (int16)fifo[2];
+ } else if((fifo[0] & 0xfff8) == 0x9400) {
+ // RRCT
+ line(cpx, cpy, cpx + (int16)fifo[1], cpy, fifo[0] & 0xff);
+ line(cpx + (int16)fifo[1], cpy, cpx + (int16)fifo[1], cpy + (int16)fifo[2], fifo[0] & 0xff);
+ line(cpx + (int16)fifo[1], cpy + (int16)fifo[2], cpx, cpy + (int16)fifo[2], fifo[0] & 0xff);
+ line(cpx, cpy + (int16)fifo[2], cpx, cpy, fifo[0] & 0xff);
+ cpx += (int16)fifo[1];
+ cpy += (int16)fifo[2];
+ } else if((fifo[0] & 0xfff8) == 0xa400) {
+ // RPLG added
+ int sx = cpx;
+ int sy = cpy;
+ for(int nseg = 0; nseg < fifo[1]; nseg++) {
+ int ex = sx + (int16)fifo[2 + nseg * 2];
+ int ey = sy + (int16)fifo[2 + nseg * 2 + 1];
+ line(sx, sy, ex, ey, fifo[0] & 7);
+ sx = ex;
+ sy = ey;
+ }
+ line(sx, sy, cpx, cpy, fifo[0] & 7);
+ } else if((fifo[0] & 0xfff8) == 0xc000) {
+ // AFRCT
+ int16 pcx = fifo[1], pcy = fifo[2];
+ int16 ax = pcx - cpx, ay = pcy - cpy;
+ int16 xx = cpx, yy = cpy;
+ for(;;) {
+ for(;;) {
+ dot(xx, yy, fifo[0] & 7, cl0);
+ if(ax == 0) {
+ break;
+ }
+ if(ax > 0) {
+ xx++;
+ ax--;
+ } else {
+ xx--;
+ ax++;
+ }
+ }
+ ax = pcx - cpx;
+ if(pcy < cpy) {
+ yy--;
+ xx -= ax;
+ if(ay == 0) {
+ break;
+ }
+ ay++;
+ } else {
+ yy++;
+ xx -= ax;
+ if(ay == 0) {
+ break;
+ }
+ ay--;
+ }
+ }
+ } else if((fifo[0] & 0xfff8) == 0xc400) {
+ // RFRCT
+ line(cpx, cpy, cpx + (int16)fifo[1], cpy, fifo[0] & 0xff);
+ line(cpx + fifo[1], cpy, cpx + fifo[1], cpy + fifo[2], fifo[0] & 0xff);
+ line(cpx + fifo[1], cpy + fifo[2], cpx, cpy + fifo[2], fifo[0] & 0xff);
+ line(cpx, cpy + fifo[2], cpx, cpy, fifo[0] & 0xff);
+ cpx=cpx + (int16)fifo[1];
+ cpy=cpy + (int16)fifo[2];
+ } else if(fifo[0] == 0xc800) {
+ // PAINT
+ paint(cpx, cpy, cl0);
+ } else if((fifo[0] & 0xfff8) == 0xcc00) {
+ // DOT
+ dot(cpx, cpy, fifo[0] & 0xff, cl0);
+ } else if((fifo[0] & 0xf000) == 0xd000) {
+ // PTN
+ ptn(fifo[0], psx, psy, pex - psx, pey - psy);
+ if(!(fifo[0] & 0x800)) {
+ switch(fifo[0] & 0x700) {
+ case 0x000:
+ if(pey - psy > 0) {
+ cpy += pey - psy;
+ } else {
+ cpy -= pey - psy;
+ }
+ break;
+ case 0x100:
+ // missing
+ break;
+ case 0x200:
+ if(pey - psy > 0) {
+ cpx += pey - psy;
+ } else {
+ cpx -= pey - psy;
+ }
+ break;
+ case 0x300:
+ // missing
+ break;
+ case 0x400:
+ if(pey - psy > 0) {
+ cpy -= pey - psy;
+ } else {
+ cpy += pey - psy;
+ }
+ break;
+ case 0x500:
+ // missing
+ break;
+ case 0x600:
+ if(pey - psy > 0) {
+ cpx -= pey - psy;
+ } else {
+ cpx += pey - psy;
+ }
+ break;
+ case 0x700:
+ // missing
+ break;
+ }
+ } else {
+ // missing
+ }
+ } else if((fifo[0] & 0xf018) == 0xe000) {
+ // AGCPY
+ agcpy(fifo[0], (int16)fifo[1], (int16)fifo[2], cpx, cpy, fifo[3], fifo[4]);
+ switch(fifo[0] & 0x700) {
+ case 0x000:
+ if(fifo[4] > 0) {
+ cpy += fifo[4];
+ } else {
+ cpy -= fifo[4];
+ }
+ break;
+ case 0x100:
+ if(fifo[4] > 0) {
+ cpy -= fifo[4];
+ } else {
+ cpy += fifo[4];
+ }
+ break;
+ case 0x200:
+ if(fifo[4] > 0) {
+ cpy += fifo[4];
+ } else {
+ cpy -= fifo[4];
+ }
+ break;
+ case 0x300:
+ if(fifo[4] > 0) {
+ cpy -= fifo[4];
+ } else {
+ cpy += fifo[4];
+ }
+ break;
+ case 0x400:
+ if(fifo[3] > 0) {
+ cpx += fifo[3];
+ } else {
+ cpx -= fifo[3];
+ }
+ break;
+ case 0x500:
+ if(fifo[3] > 0) {
+ cpx += fifo[3];
+ } else {
+ cpx -= fifo[3];
+ }
+ break;
+ case 0x600:
+ if(fifo[3] > 0) {
+ cpx -= fifo[3];
+ } else {
+ cpx += fifo[3];
+ }
+ break;
+ case 0x700:
+ if(fifo[3] > 0) {
+ cpx -= fifo[3];
+ } else {
+ cpx += fifo[3];
+ }
+ break;
+ }
+ } else {
+ emu->out_debug_log(_T("unsupported command\n"));
+ }
+ fifo_ptr = 0;
+ }
+}
+
+void HD63484::doclr16(int opcode, uint16 fill, int *dst, int _ax, int _ay)
+{
+ int ax = _ax, ay = _ay;
+
+ for(;;) {
+ for(;;) {
+ switch(opcode & 3) {
+ case 0:
+ vram[*dst & ADDR_MASK] = fill;
+ break;
+ case 1:
+ vram[*dst & ADDR_MASK] |= fill;
+ break;
+ case 2:
+ vram[*dst & ADDR_MASK] &= fill;
+ break;
+ case 3:
+ vram[*dst & ADDR_MASK] ^= fill;
+ break;
+ }
+ if(ax == 0) {
+ break;
+ }
+ if(ax > 0) {
+ *dst = (*dst + 1) & ADDR_MASK;
+ ax--;
+ } else {
+ *dst = (*dst - 1) & ADDR_MASK;
+ ax++;
+ }
+ }
+ ax = _ax;
+ if(_ay < 0) {
+ *dst = (*dst + (MWR1 & 0xfff) - ax) & ADDR_MASK;
+ if(ay == 0) {
+ break;
+ }
+ ay++;
+ } else {
+ *dst = (*dst - (MWR1 & 0xfff) - ax) & ADDR_MASK;
+ if(ay == 0) {
+ break;
+ }
+ ay--;
+ }
+ }
+}
+
+void HD63484::docpy16(int opcode, int src, int *dst, int _ax, int _ay)
+{
+ int dstep1, dstep2;
+ int ax = _ax, ay = _ay;
+
+ switch(opcode & 0x700) {
+ case 0x000: dstep1 = 1; dstep2 = -1 * (MWR1 & 0xfff) - ax * dstep1; break;
+ case 0x100: dstep1 = 1; dstep2 = (MWR1 & 0xfff) - ax * dstep1; break;
+ case 0x200: dstep1 = -1; dstep2 = -1 * (MWR1 & 0xfff) + ax * dstep1; break;
+ case 0x300: dstep1 = -1; dstep2 = (MWR1 & 0xfff) + ax * dstep1; break;
+ case 0x400: dstep1 = -1 * (MWR1 & 0xfff); dstep2 = 1 - ay * dstep1; break;
+ case 0x500: dstep1 = (MWR1 & 0xfff); dstep2 = 1 - ay * dstep1; break;
+ case 0x600: dstep1 = -1 * (MWR1 & 0xfff); dstep2 = -1 + ay * dstep1; break;
+ case 0x700: dstep1 = (MWR1 & 0xfff); dstep2 = -1 + ay * dstep1; break;
+ }
+ for(;;) {
+ for(;;) {
+ switch(opcode & 7) {
+ case 0:
+ vram[*dst] = vram[src];
+ break;
+ case 1:
+ vram[*dst] |= vram[src];
+ break;
+ case 2:
+ vram[*dst] &= vram[src];
+ break;
+ case 3:
+ vram[*dst] ^= vram[src];
+ break;
+ case 4:
+ if(vram[*dst] == (ccmp & 0xff)) {
+ vram[*dst] = vram[src];
+ }
+ break;
+ case 5:
+ if(vram[*dst] != (ccmp & 0xff)) {
+ vram[*dst] = vram[src];
+ }
+ break;
+ case 6:
+ if(vram[*dst] < vram[src]) {
+ vram[*dst] = vram[src];
+ }
+ break;
+ case 7:
+ if(vram[*dst] > vram[src]) {
+ vram[*dst] = vram[src];
+ }
+ break;
+ }
+ if(opcode & 0x800) {
+ if(ay == 0) {
+ break;
+ }
+ if(_ay > 0) {
+ src = (src - (MWR1 & 0xfff)) & ADDR_MASK;
+ *dst = (*dst + dstep1) & ADDR_MASK;
+ ay--;
+ } else {
+ src = (src + (MWR1 & 0xfff)) & ADDR_MASK;
+ *dst = (*dst + dstep1) & ADDR_MASK;
+ ay++;
+ }
+ } else {
+ if(ax == 0) {
+ break;
+ }
+ if(ax > 0) {
+ src = (src + 1) & ADDR_MASK;
+ *dst = (*dst + dstep1) & ADDR_MASK;
+ ax--;
+ } else {
+ src = (src - 1) & ADDR_MASK;
+ *dst = (*dst + dstep1) & ADDR_MASK;
+ ax++;
+ }
+ }
+ }
+ if(opcode & 0x800) {
+ ay = _ay;
+ if(_ax < 0) {
+ src = (src - 1 + ay * (MWR1 & 0xfff)) & ADDR_MASK;
+ *dst = (*dst + dstep2) & ADDR_MASK;
+ if(ax == 0) {
+ break;
+ }
+ ax++;
+ } else {
+ src = (src + 1 - ay * (MWR1 & 0xfff)) & ADDR_MASK;
+ *dst = (*dst + dstep2) & ADDR_MASK;
+ if(ax == 0) {
+ break;
+ }
+ ax--;
+ }
+ } else {
+ ax = _ax;
+ if(_ay < 0) {
+ src = (src + (MWR1 & 0xfff) - ax) & ADDR_MASK;
+ *dst = (*dst + dstep2) & ADDR_MASK;
+ if(ay == 0) {
+ break;
+ }
+ ay++;
+ } else {
+ src = (src - (MWR1 & 0xfff) - ax) & ADDR_MASK;
+ *dst = (*dst + dstep2) & ADDR_MASK;
+ if(ay == 0) {
+ break;
+ }
+ ay--;
+ }
+ }
+ }
+}
+
+int HD63484::org_first_pixel(int _org_dpd)
+{
+ int gbm = (CCR & 0x700) >> 8;
+
+ switch(gbm) {
+ case 0:
+ return (_org_dpd & 0xf);
+ case 1:
+ return (_org_dpd & 0xf) >> 1;
+ case 2:
+ return (_org_dpd & 0xf) >> 2;
+ case 3:
+ return (_org_dpd & 0xf) >> 3;
+ case 4:
+ return 0;
+ }
+ emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));
+ return 0;
+}
+
+void HD63484::dot(int x, int y, int opm, uint16 color)
+{
+ int dst, x_int, x_mod, bpp;
+ uint16 color_shifted, bitmask, bitmask_shifted;
+
+ x += org_first_pixel(org_dpd);
+
+ switch((CCR & 0x700) >> 8) {
+ case 0:
+ bpp = 1;
+ bitmask = 0x0001;
+ break;
+ case 1:
+ bpp = 2;
+ bitmask = 0x0003;
+ break;
+ case 2:
+ bpp = 4;
+ bitmask = 0x000f;
+ break;
+ case 3:
+ bpp = 8;
+ bitmask = 0x00ff;
+ break;
+ case 4:
+ bpp = 16;
+ bitmask = 0xffff;
+ break;
+ default:
+ emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));
+ bpp = 0;
+ bitmask = 0x0000;
+ }
+ if(x >= 0) {
+ x_int = x / (16 / bpp);
+ x_mod = x % (16 / bpp);
+ } else {
+ x_int = x / (16 / bpp);
+ x_mod = -1 * (x % (16 / bpp));
+ if(x_mod) {
+ x_int--;
+ x_mod = (16 / bpp) - x_mod;
+ }
+ }
+
+ color &= bitmask;
+ bitmask_shifted = bitmask << (x_mod * bpp);
+ color_shifted = color << (x_mod * bpp);
+ dst = (org + x_int - y * (MWR1 & 0xfff)) & ADDR_MASK;
+
+ switch(opm) {
+ case 0:
+ vram[dst] = (vram[dst] & ~bitmask_shifted) | color_shifted;
+ break;
+ case 1:
+ vram[dst] = vram[dst] | color_shifted;
+ break;
+ case 2:
+ vram[dst] = vram[dst] & ((vram[dst] & ~bitmask_shifted) | color_shifted);
+ break;
+ case 3:
+ vram[dst] = vram[dst] ^ color_shifted;
+ break;
+ case 4:
+ if(get_pixel(x, y) == (ccmp & bitmask)) {
+ vram[dst] = (vram[dst] & ~bitmask_shifted) | color_shifted;
+ }
+ break;
+ case 5:
+ if(get_pixel(x, y) != (ccmp & bitmask)) {
+ vram[dst] = (vram[dst] & ~bitmask_shifted) | color_shifted;
+ }
+ break;
+ case 6:
+ if(get_pixel(x, y) < (cl0 & bitmask)) {
+ vram[dst] = (vram[dst] & ~bitmask_shifted) | color_shifted;
+ }
+ break;
+ case 7:
+ if(get_pixel(x, y) > (cl0 & bitmask)) {
+ vram[dst] = (vram[dst] & ~bitmask_shifted) | color_shifted;
+ }
+ break;
+ }
+}
+
+int HD63484::get_pixel(int x, int y)
+{
+ int dst, x_int, x_mod, bpp;
+ uint16 bitmask, bitmask_shifted;
+
+ switch((CCR & 0x700) >> 8) {
+ case 0:
+ bpp = 1;
+ bitmask = 0x0001;
+ break;
+ case 1:
+ bpp = 2;
+ bitmask = 0x0003;
+ break;
+ case 2:
+ bpp = 4;
+ bitmask = 0x000f;
+ break;
+ case 3:
+ bpp = 8;
+ bitmask = 0x00ff;
+ break;
+ case 4:
+ bpp = 16;
+ bitmask = 0xffff;
+ break;
+ default:
+ emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));
+ bpp = 0;
+ bitmask = 0x0000;
+ }
+ if(x >= 0) {
+ x_int = x / (16 / bpp);
+ x_mod = x % (16 / bpp);
+ } else {
+ x_int = x / (16 / bpp);
+ x_mod = -1 * (x % (16 / bpp));
+ if(x_mod) {
+ x_int--;
+ x_mod = (16 / bpp) - x_mod;
+ }
+ }
+ bitmask_shifted = bitmask << (x_mod * bpp);
+ dst = (org + x_int - y * (MWR1 & 0xfff)) & ADDR_MASK;
+
+ return ((vram[dst] & bitmask_shifted) >> (x_mod * bpp));
+}
+
+int HD63484::get_pixel_ptn(int x, int y)
+{
+ int dst, x_int, x_mod, bpp;
+ uint16 bitmask, bitmask_shifted;
+
+ bpp = 1;
+ bitmask = 1;
+
+ if(x >= 0) {
+ x_int = x / (16 / bpp);
+ x_mod = x % (16 / bpp);
+ } else {
+ x_int = x / (16 / bpp);
+ x_mod = -1 * (x % (16 / bpp));
+ if(x_mod) {
+ x_int--;
+ x_mod = (16 / bpp) - x_mod;
+ }
+ }
+ bitmask_shifted = bitmask << (x_mod * bpp);
+ dst = (x_int + y * 1);
+
+ if((pattern[dst] & bitmask_shifted) >> (x_mod * bpp)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void HD63484::agcpy(int opcode, int src_x, int src_y, int dst_x, int dst_y, int16 _ax, int16 _ay)
+{
+ int dst_step1_x, dst_step1_y, dst_step2_x, dst_step2_y;
+ int src_step1_x, src_step1_y, src_step2_x, src_step2_y;
+ int ax = _ax;
+ int ay = _ay;
+ int ax_neg = (_ax >= 0) ? 1 : -1;
+ int ay_neg = (_ay >= 0) ? 1 : -1;
+ int xxs = src_x;
+ int yys = src_y;
+ int xxd = dst_x;
+ int yyd = dst_y;
+
+ if(opcode & 0x800) {
+ switch(opcode & 0x700) {
+ case 0x000: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ay_neg * ay; dst_step2_y = 1; break;
+ case 0x100: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ay_neg * ay; dst_step2_y = -1; break;
+ case 0x200: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ay_neg * ay; dst_step2_y = 1; break;
+ case 0x300: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ay_neg * ay; dst_step2_y = -1; break;
+ case 0x400: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = 1; dst_step2_y = -ay_neg * ay; break;
+ case 0x500: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = 1; dst_step2_y = ay_neg * ay; break;
+ case 0x600: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = -1; dst_step2_y = -ay_neg * ay; break;
+ case 0x700: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = -1; dst_step2_y = ay_neg * ay; break;
+ }
+ src_step1_x = 0;
+ src_step1_y = (_ay >= 0) ? 1 : -1;
+ src_step2_x = (_ax >= 0) ? 1 : -1;
+ src_step2_y = -ay;
+ } else {
+ switch(opcode & 0x700) {
+ case 0x000: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ax_neg * ax; dst_step2_y = 1; break;
+ case 0x100: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ax_neg * ax; dst_step2_y = -1; break;
+ case 0x200: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ax_neg * ax; dst_step2_y = 1; break;
+ case 0x300: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ax_neg * ax; dst_step2_y = -1; break;
+ case 0x400: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = 1; dst_step2_y = ax_neg * ax; break;
+ case 0x500: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = 1; dst_step2_y = -ax_neg * ax; break;
+ case 0x600: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = -1; dst_step2_y = ax_neg * ax; break;
+ case 0x700: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = -1; dst_step2_y = -ax_neg * ax; break;
+ }
+ src_step1_x = (_ax >= 0) ? 1 : -1;
+ src_step1_y = 0;
+ src_step2_x = -ax;
+ src_step2_y = (_ay >= 0) ? 1 : -1;
+ }
+ for(;;) {
+ for(;;) {
+ dot(xxd, yyd, opcode & 7, get_pixel(xxs, yys));
+ if(opcode & 0x800) {
+ if(ay == 0) {
+ break;
+ }
+ if(_ay > 0) {
+ xxs += src_step1_x;
+ yys += src_step1_y;
+ xxd += dst_step1_x;
+ yyd += dst_step1_y;
+ ay--;
+ } else {
+ xxs += src_step1_x;
+ yys += src_step1_y;
+ xxd += dst_step1_x;
+ yyd += dst_step1_y;
+ ay++;
+ }
+ } else {
+ if(ax == 0) {
+ break;
+ }
+ if(ax > 0) {
+ xxs += src_step1_x;
+ yys += src_step1_y;
+ xxd += dst_step1_x;
+ yyd += dst_step1_y;
+ ax--;
+ } else {
+ xxs += src_step1_x;
+ yys += src_step1_y;
+ xxd += dst_step1_x;
+ yyd += dst_step1_y;
+ ax++;
+ }
+ }
+ }
+ if(opcode & 0x800) {
+ ay = _ay;
+ if(_ax < 0) {
+ xxs += src_step2_x;
+ yys += src_step2_y;
+ xxd += dst_step2_x;
+ yyd += dst_step2_y;
+ if(ax == 0) {
+ break;
+ }
+ ax++;
+ } else {
+ xxs += src_step2_x;
+ yys += src_step2_y;
+ xxd += dst_step2_x;
+ yyd += dst_step2_y;
+ if(ax == 0) {
+ break;
+ }
+ ax--;
+ }
+ } else {
+ ax = _ax;
+ if(_ay < 0) {
+ xxs += src_step2_x;
+ yys += src_step2_y;
+ xxd += dst_step2_x;
+ yyd += dst_step2_y;
+ if(ay == 0) {
+ break;
+ }
+ ay++;
+ } else {
+ xxs += src_step2_x;
+ yys += src_step2_y;
+ xxd += dst_step2_x;
+ yyd += dst_step2_y;
+ if(ay == 0) {
+ break;
+ }
+ ay--;
+ }
+ }
+ }
+}
+
+void HD63484::ptn(int opcode, int src_x, int src_y, int16 _ax, int16 _ay)
+{
+ int dst_step1_x = 0, dst_step1_y = 0, dst_step2_x = 0, dst_step2_y = 0;
+ int src_step1_x = 1, src_step1_y = 0, src_step2_x = -_ax, src_step2_y = 1;
+ int ax = _ax;
+ int ay = _ay;
+ int ax_neg = (_ax >= 0) ? 1 : -1;
+ int ay_neg = (_ay >= 0) ? 1 : -1;
+ int xxs = src_x;
+ int yys = src_y;
+ int xxd = cpx;
+ int yyd = cpy;
+ int getpixel;
+
+ if(opcode & 0x800) {
+ emu->out_debug_log(_T("HD63484 ptn not supported\n"));
+ } else {
+ switch(opcode & 0x700) {
+ case 0x000: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ax_neg * ax; dst_step2_y = 1; break;
+ case 0x100: emu->out_debug_log(_T("HD63484 ptn not supported\n")); break;
+ case 0x200: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = -1; dst_step2_y = -ax_neg * ax; break;
+ case 0x300: emu->out_debug_log(_T("HD63484 ptn not supported\n")); break;
+ case 0x400: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ax_neg * ax; dst_step2_y = -1; break;
+ case 0x500: emu->out_debug_log(_T("HD63484 ptn not supported\n")); break;
+ case 0x600: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = 1; dst_step2_y = ax_neg * ax; break;
+ case 0x700: emu->out_debug_log(_T("HD63484 ptn not supported\n")); break;
+ }
+ }
+ for(;;) {
+ for(;;) {
+ getpixel = get_pixel_ptn(xxs, yys);
+ switch((opcode >> 3) & 3) {
+ case 0:
+ if(getpixel) {
+ dot(xxd, yyd, opcode & 7, cl1);
+ } else {
+ dot(xxd, yyd, opcode & 7, cl0);
+ }
+ break;
+ case 1:
+ if(getpixel) {
+ dot(xxd, yyd, opcode & 7, cl1);
+ }
+ break;
+ case 2:
+ if(getpixel == 0) {
+ dot(xxd, yyd, opcode & 7, cl0);
+ }
+ break;
+ case 3:
+ emu->out_debug_log(_T("HD63484 ptn not supported\n"));
+ break;
+ }
+ if(opcode & 0x800) {
+ if(ay == 0) {
+ break;
+ }
+ if(_ay > 0) {
+ xxs += src_step1_x;
+ yys += src_step1_y;
+ xxd += dst_step1_x;
+ yyd += dst_step1_y;
+ ay--;
+ } else {
+ xxs += src_step1_x;
+ yys += src_step1_y;
+ xxd += dst_step1_x;
+ yyd += dst_step1_y;
+ ay++;
+ }
+ } else {
+ if(ax == 0) {
+ break;
+ }
+ if(ax > 0) {
+ xxs += src_step1_x;
+ yys += src_step1_y;
+ xxd += dst_step1_x;
+ yyd += dst_step1_y;
+ ax--;
+ } else {
+ xxs += src_step1_x;
+ yys += src_step1_y;
+ xxd += dst_step1_x;
+ yyd += dst_step1_y;
+ ax++;
+ }
+ }
+ }
+ if(opcode & 0x800) {
+ ay = _ay;
+ if(_ax < 0) {
+ xxs += src_step2_x;
+ yys += src_step2_y;
+ xxd += dst_step2_x;
+ yyd += dst_step2_y;
+ if(ax == 0) break;
+ ax++;
+ } else {
+ xxs += src_step2_x;
+ yys += src_step2_y;
+ xxd += dst_step2_x;
+ yyd += dst_step2_y;
+ if(ax == 0) break;
+ ax--;
+ }
+ } else {
+ ax = _ax;
+ if(_ay < 0) {
+ xxs += src_step2_x;
+ yys += src_step2_y;
+ xxd += dst_step2_x;
+ yyd += dst_step2_y;
+ if(ay == 0) break;
+ ay++;
+ } else {
+ xxs += src_step2_x;
+ yys += src_step2_y;
+ xxd += dst_step2_x;
+ yyd += dst_step2_y;
+ if(ay == 0) break;
+ ay--;
+ }
+ }
+ }
+}
+
+void HD63484::line(int16 sx, int16 sy, int16 ex, int16 ey, int16 col)
+{
+ int cpx_t = sx;
+ int cpy_t = sy;
+ int16 ax = ex - sx;
+ int16 ay = ey - sy;
+
+ if(abs(ax) >= abs(ay)) {
+ while(ax) {
+ dot(cpx_t, cpy_t, col & 7, cl0);
+ if(ax > 0) {
+ cpx_t++;
+ ax--;
+ } else {
+ cpx_t--;
+ ax++;
+ }
+ cpy_t = sy + ay * (cpx_t - sx) / (ex - sx);
+ }
+ } else {
+ while(ay) {
+ dot(cpx_t, cpy_t, col & 7, cl0);
+ if(ay > 0) {
+ cpy_t++;
+ ay--;
+ } else {
+ cpy_t--;
+ ay++;
+ }
+ cpx_t = sx + ax * (cpy_t - sy) / (ey - sy);
+ }
+ }
+}
+
+void HD63484::paint(int sx, int sy, int col)
+{
+ int getpixel;
+ dot(sx, sy, 0, col);
+
+ getpixel = get_pixel(sx + 1, sy);
+ switch((CCR & 0x700) >> 8) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0);
+ break;
+ case 3:
+ getpixel = (getpixel << 8) | (getpixel << 0);
+ break;
+ case 4:
+ break;
+ default:
+ emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));
+ }
+ if((getpixel != col) && (getpixel != edg)) {
+ sx++;
+ paint(sx, sy, col);
+ sx--;
+ }
+
+ getpixel = get_pixel(sx - 1, sy);
+ switch((CCR & 0x700) >> 8) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0);
+ break;
+ case 3:
+ getpixel = (getpixel << 8) | (getpixel << 0);
+ break;
+ case 4:
+ break;
+ default:
+ emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));
+ }
+ if((getpixel != col) && (getpixel != edg)) {
+ sx--;
+ paint(sx, sy, col);
+ sx++;
+ }
+
+ getpixel = get_pixel(sx, sy + 1);
+ switch((CCR & 0x700) >> 8) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0);
+ break;
+ case 3:
+ getpixel = (getpixel << 8) | (getpixel << 0);
+ break;
+ case 4:
+ break;
+ default:
+ emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));
+ }
+ if((getpixel != col) && (getpixel != edg)) {
+ sy++;
+ paint(sx, sy, col);
+ sy--;
+ }
+
+ getpixel = get_pixel(sx, sy - 1);
+ switch((CCR & 0x700) >> 8) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0);
+ break;
+ case 3:
+ getpixel = (getpixel << 8) | (getpixel << 0);
+ break;
+ case 4:
+ break;
+ default:
+ emu->out_debug_log(_T("HD63484 graphic bit mode not supported\n"));
+ }
+ if((getpixel != col) && (getpixel != edg)) {
+ sy--;
+ paint(sx, sy, col);
+ sy++;
+ }
+}
+