OSDN Git Service

[General] Convert sourcecode's CRLF format: DOS(WINDOWS) to Unix, to apply patches...
[csp-qt/common_source_project-fm7.git] / source / src / vm / hd63484.cpp
index 8a0ce5c..af6a102 100644 (file)
-/*\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++;
+       }
+}
+