Diff for /np2/lio/gput1.c between versions 1.1.1.1 and 1.10

version 1.1.1.1, 2003/10/16 17:58:27 version 1.10, 2004/02/21 20:48:52
Line 1 Line 1
 #include        "compiler.h"  #include        "compiler.h"
 #include        "i286.h"  #include        "cpucore.h"
 #include        "memory.h"  #include        "pccore.h"
   #include        "iocore.h"
   #include        "bios.h"
 #include        "lio.h"  #include        "lio.h"
   #include        "vram.h"
   
   
 typedef struct {  typedef struct {
           BYTE    x1[2];
           BYTE    y1[2];
           BYTE    x2[2];
           BYTE    y2[2];
           BYTE    off[2];
           BYTE    seg[2];
           BYTE    leng[2];
   } GGET;
   
   typedef struct {
           BYTE    x[2];
           BYTE    y[2];
           BYTE    off[2];
           BYTE    seg[2];
           BYTE    leng[2];
           BYTE    mode;
           BYTE    colorsw;
           BYTE    fg;
           BYTE    bg;
   } GPUT1;
   
   typedef struct {
           BYTE    x[2];
           BYTE    y[2];
           BYTE    chr[2];
           BYTE    mode;
           BYTE    colorsw;
           BYTE    fg;
           BYTE    bg;
   } GPUT2;
   
   typedef struct {
         SINT16  x;          SINT16  x;
         SINT16  y;          SINT16  y;
           UINT16  width;
           UINT16  height;
         UINT16  off;          UINT16  off;
         UINT16  seg;          UINT16  seg;
         UINT16  leng;          UINT8   mode;
         BYTE    mode;          UINT8   sw;
         BYTE    colsw;          UINT8   fg;
         BYTE    fgcolor;          UINT8   bg;
         BYTE    bgcolor;  } LIOPUT;
 } MEMGPUT1;  
   typedef struct {
           BYTE    *baseptr;
           UINT    addr;
           UINT    sft;
           UINT    width;
           UINT8   mask;
   } GETCNTX;
   
   typedef struct {
           BYTE    *baseptr;
           UINT    addr;
           UINT    sft;
           UINT    width;
           UINT8   maskl;
           UINT8   maskr;
           UINT8   masklr;
           UINT8   mask;
           BYTE    pat[84];
   } PUTCNTX;
   
   
   static void getvram(const GETCNTX *gt, BYTE *dst) {
   
           BYTE    *baseptr;
           UINT    addr;
           UINT    width;
           UINT    dat;
           UINT    sft;
   
           baseptr = gt->baseptr;
           addr = gt->addr;
           width = gt->width;
           sft = 8 - gt->sft;
           dat = baseptr[LOW15(addr)];
           addr++;
           while(width > 8) {
                   width -= 8;
                   dat = (dat << 8) + baseptr[LOW15(addr)];
                   addr++;
                   *dst = (UINT8)(dat >> sft);
                   dst++;
           }
           dat = (dat << 8) + baseptr[LOW15(addr)];
           *dst = (UINT8)((dat >> sft) & gt->mask);
   }
   
   static void setdirty(UINT addr, UINT width, UINT height, REG8 bit) {
   
           UINT    r;
   
           gdcs.grphdisp |= bit;
           width = (width + 7) >> 3;
           while(height--) {
                   r = 0;
                   while(r < width) {
                           vramupdate[LOW15(addr + r)] |= bit;
                           r++;
                   }
                   addr += 80;
           }
   }
   
   static void putor(const PUTCNTX *pt) {
   
           BYTE    *baseptr;
           UINT    addr;
   const BYTE      *src;
           UINT    width;
           UINT    dat;
   
           baseptr = pt->baseptr;
           addr = pt->addr;
           src = pt->pat;
           width = pt->width;
           dat = *src++;
           if ((pt->sft + width) < 8) {
                   baseptr[LOW15(addr)] |= (UINT8)((dat >> pt->sft) & pt->masklr);
           }
           else {
                   baseptr[LOW15(addr)] |= (UINT8)(dat >> pt->sft) & pt->maskl;
                   addr++;
                   width -= (8 - pt->sft);
                   while(width > 8) {
                           width -= 8;
                           dat = (dat << 8) + (*src);
                           src++;
                           baseptr[LOW15(addr)] |= (UINT8)(dat >> pt->sft);
                           addr++;
                   }
                   if (width) {
                           dat = (dat << 8) + (*src);
                           baseptr[LOW15(addr)] |= (UINT8)(dat >> pt->sft) & pt->maskr;
                   }
           }
   }
   
   static void putorn(const PUTCNTX *pt) {
   
           BYTE    *baseptr;
           UINT    addr;
   const BYTE      *src;
           UINT    width;
           UINT    dat;
   
           baseptr = pt->baseptr;
           addr = pt->addr;
           src = pt->pat;
           width = pt->width;
           dat = *src++;
           if ((pt->sft + width) < 8) {
                   baseptr[LOW15(addr)] |= (UINT8)(((~dat) >> pt->sft) & pt->masklr);
           }
           else {
                   baseptr[LOW15(addr)] |= (UINT8)(((~dat) >> pt->sft) & pt->maskl);
                   addr++;
                   width -= (8 - pt->sft);
                   while(width > 8) {
                           width -= 8;
                           dat = (dat << 8) + (*src);
                           src++;
                           baseptr[LOW15(addr)] |= (UINT8)((~dat) >> pt->sft);
                           addr++;
                   }
                   if (width) {
                           dat = (dat << 8) + (*src);
                           baseptr[LOW15(addr)] |= (UINT8)(((~dat) >> pt->sft) & pt->maskr);
                   }
           }
   }
   
   static void putand(const PUTCNTX *pt) {
   
           BYTE    *baseptr;
           UINT    addr;
   const BYTE      *src;
           UINT    width;
           UINT    dat;
   
           baseptr = pt->baseptr;
           addr = pt->addr;
           src = pt->pat;
           width = pt->width;
           dat = *src++;
           if ((pt->sft + width) < 8) {
                   baseptr[LOW15(addr)] &= (UINT8)((dat >> pt->sft) | (~pt->masklr));
           }
           else {
                   baseptr[LOW15(addr)] &= (UINT8)((dat >> pt->sft) | (~pt->maskl));
                   addr++;
                   width -= (8 - pt->sft);
                   while(width > 8) {
                           width -= 8;
                           dat = (dat << 8) + (*src);
                           src++;
                           baseptr[LOW15(addr)] &= (UINT8)(dat >> pt->sft);
                           addr++;
                   }
                   if (width) {
                           dat = (dat << 8) + (*src);
                           baseptr[LOW15(addr)] &= (UINT8)((dat >> pt->sft) | (~pt->maskr));
                   }
           }
   }
   
   static void putandn(const PUTCNTX *pt) {
   
           BYTE    *baseptr;
           UINT    addr;
   const BYTE      *src;
           UINT    width;
           UINT    dat;
   
           baseptr = pt->baseptr;
           addr = pt->addr;
           src = pt->pat;
           width = pt->width;
           dat = *src++;
           if ((pt->sft + width) < 8) {
                   baseptr[LOW15(addr)] &= (UINT8)(~((dat >> pt->sft) & pt->masklr));
           }
           else {
                   baseptr[LOW15(addr)] &= (UINT8)(~((dat >> pt->sft) & pt->maskl));
                   addr++;
                   width -= (8 - pt->sft);
                   while(width > 8) {
                           width -= 8;
                           dat = (dat << 8) + (*src);
                           src++;
                           baseptr[LOW15(addr)] &= (UINT8)((~dat) >> pt->sft);
                           addr++;
                   }
                   if (width) {
                           dat = (dat << 8) + (*src);
                           baseptr[LOW15(addr)] &= (UINT8)(~((dat >> pt->sft) & pt->maskr));
                   }
           }
   }
   
   static void putxor(const PUTCNTX *pt) {
   
           BYTE    *baseptr;
           UINT    addr;
   const BYTE      *src;
           UINT    width;
           UINT    dat;
   
           baseptr = pt->baseptr;
           addr = pt->addr;
           src = pt->pat;
           width = pt->width;
           dat = *src++;
           if ((pt->sft + width) < 8) {
                   baseptr[LOW15(addr)] ^= (UINT8)((dat >> pt->sft) & pt->masklr);
           }
           else {
                   baseptr[LOW15(addr)] ^= (UINT8)(dat >> pt->sft) & pt->maskl;
                   addr++;
                   width -= (8 - pt->sft);
                   while(width > 8) {
                           width -= 8;
                           dat = (dat << 8) + (*src);
                           src++;
                           baseptr[LOW15(addr)] ^= (UINT8)(dat >> pt->sft);
                           addr++;
                   }
                   if (width) {
                           dat = (dat << 8) + (*src);
                           baseptr[LOW15(addr)] ^= (UINT8)(dat >> pt->sft) & pt->maskr;
                   }
           }
   }
   
   static void putxorn(const PUTCNTX *pt) {
   
           BYTE    *baseptr;
           UINT    addr;
   const BYTE      *src;
           UINT    width;
           UINT    dat;
   
           baseptr = pt->baseptr;
           addr = pt->addr;
           src = pt->pat;
           width = pt->width;
           dat = *src++;
           if ((pt->sft + width) < 8) {
                   baseptr[LOW15(addr)] ^= (UINT8)(((~dat) >> pt->sft) & pt->masklr);
           }
           else {
                   baseptr[LOW15(addr)] ^= (UINT8)(((~dat) >> pt->sft) & pt->maskl);
                   addr++;
                   width -= (8 - pt->sft);
                   while(width > 8) {
                           width -= 8;
                           dat = (dat << 8) + (*src);
                           src++;
                           baseptr[LOW15(addr)] ^= (UINT8)((~dat) >> pt->sft);
                           addr++;
                   }
                   if (width) {
                           dat = (dat << 8) + (*src);
                           baseptr[LOW15(addr)] ^= (UINT8)(((~dat) >> pt->sft) & pt->maskr);
                   }
           }
   }
   
   
   // ----
   
   static REG8 putsub(GLIO lio, const LIOPUT *lput) {
   
           UINT    addr;
           PUTCNTX pt;
           UINT    datacnt;
           UINT    off;
           UINT    height;
           UINT    flag;
           UINT    pl;
           UINT    writecnt;
   
           if ((lput->x < lio->draw.x1) ||
                   (lput->y < lio->draw.y1) ||
                   ((lput->x + lput->width - 1) > lio->draw.x2) ||
                   ((lput->y + lput->height - 1) > lio->draw.y2)) {
                   return(LIO_ILLEGALFUNC);
           }
           if ((lput->width <= 0) || (lput->height <= 0)) {
                   return(LIO_SUCCESS);
           }
   
           addr = (lput->x >> 3) + (lput->y * 80);
           if (lio->draw.flag & LIODRAW_UPPER) {
                   addr += 16000;
           }
           setdirty(addr, (lput->x & 7) + lput->width, lput->height, lio->draw.sbit);
   
           pt.addr = addr;
           pt.sft = lput->x & 7;
           pt.width = lput->width;
           pt.maskl = (UINT8)(0xff >> pt.sft);
           pt.maskr = (UINT8)((~0x7f) >> ((pt.width + pt.sft - 1) & 7));
           pt.masklr = (UINT8)(pt.maskl >> pt.sft);
   
           datacnt = (lput->width + 7) >> 3;
           off = lput->off;
   
           flag = (lio->draw.flag & LIODRAW_4BPP)?0x0f:0x07;
           flag |= (lput->fg & 15) << 4;
           flag |= (lput->bg & 15) << 8;
   
           // さて表示。
           writecnt = 0;
           height = lput->height;
           do {
                   flag <<= 4;
                   for (pl=0; pl<4; pl++) {
                           flag >>= 1;
                           if (flag & 8) {
                                   pt.baseptr = mem + lio->draw.base + lioplaneadrs[pl];
                                   i286_memstr_read(lput->seg, off, pt.pat, datacnt);
                                   if (lput->sw) {
                                           off += datacnt;
                                   }
                                   switch(lput->mode) {
                                           case 0:         // PSET
                                                   if (flag & (8 << 4)) {
                                                           putor(&pt);
                                                   }
                                                   else {
                                                           putandn(&pt);
                                                   }
                                                   if (flag & (8 << 8)) {
                                                           putorn(&pt);
                                                   }
                                                   else {
                                                           putand(&pt);
                                                   }
                                                   writecnt += 2;
                                                   break;
   
                                           case 1:         // NOT
                                                   if (!(flag & (8 << 4))) {
                                                           putor(&pt);
                                                   }
                                                   else {
                                                           putandn(&pt);
                                                   }
                                                   if (!(flag & (8 << 8))) {
                                                           putorn(&pt);
                                                   }
                                                   else {
                                                           putand(&pt);
                                                   }
                                                   writecnt += 2;
                                                   break;
   
                                           case 2:         // OR
                                                   if (flag & (8 << 4)) {
                                                           putor(&pt);
                                                           writecnt++;
                                                   }
                                                   if (flag & (8 << 8)) {
                                                           putorn(&pt);
                                                           writecnt++;
                                                   }
                                                   break;
   
                                           case 3:         // AND
                                                   if (!(flag & (8 << 4))) {
                                                           putandn(&pt);
                                                           writecnt++;
                                                   }
                                                   if (!(flag & (8 << 8))) {
                                                           putand(&pt);
                                                           writecnt++;
                                                   }
                                                   break;
   
                                           case 4:         // XOR
                                                   if (flag & (8 << 4)) {
                                                           putxor(&pt);
                                                           writecnt++;
                                                   }
                                                   if (flag & (8 << 8)) {
                                                           putxorn(&pt);
                                                           writecnt++;
                                                   }
                                                   break;
                                   }
                           }
                   }
                   pt.addr += 80;
                   if (!lput->sw) {
                           off += datacnt;
                   }
           } while(--height);
           lio->wait += writecnt * datacnt * (10 + 10 + 10);
           return(LIO_SUCCESS);
   }
   
   
   // ---- GGET
   
   REG8 lio_gget(GLIO lio) {
   
           GGET    dat;
           SINT32  x;
           SINT32  y;
           int             x2;
           int             y2;
           UINT    off;
           UINT    seg;
           UINT32  leng;
           UINT32  size;
           UINT    datacnt;
           UINT    mask;
           GETCNTX gt;
           BYTE    pat[84];
           UINT    pl;
   
           lio_updatedraw(lio);
           i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat));
           x = (SINT16)LOADINTELWORD(dat.x1);
           y = (SINT16)LOADINTELWORD(dat.y1);
           x2 = (SINT16)LOADINTELWORD(dat.x2);
           y2 = (SINT16)LOADINTELWORD(dat.y2);
           if ((x < lio->draw.x1) || (y < lio->draw.y1) ||
                   (x2 > lio->draw.x2) || (y2 > lio->draw.y2)) {
                   return(LIO_ILLEGALFUNC);
           }
           x2 = x2 - x + 1;
           y2 = y2 - y + 1;
           if ((x2 <= 0) || (y2 <= 0)) {
                   return(LIO_ILLEGALFUNC);
           }
           off = LOADINTELWORD(dat.off);
           seg = (SINT16)LOADINTELWORD(dat.seg);
   
           datacnt = (x2 + 7) >> 3;
           size = datacnt * y2;
           leng = LOADINTELWORD(dat.leng);
           if (!(lio->draw.flag & LIODRAW_MONO)) {
                   if (lio->draw.flag & LIODRAW_4BPP) {
                           size *= 4;
                           mask = 0x0f;
                   }
                   else {
                           size *= 3;
                           mask = 0x07;
                   }
           }
           else {
                   mask = 1 << (lio->draw.flag & LIODRAW_PMASK);
           }
           if (leng < (size + 4)) {
                   return(LIO_ILLEGALFUNC);
           }
           i286_memword_write(seg, off, (REG16)x2);
           i286_memword_write(seg, off+2, (REG16)y2);
           off += 4;
           gt.addr = (x >> 3) + (y * 80);
           if (lio->draw.flag & LIODRAW_UPPER) {
                   gt.addr += 16000;
           }
           gt.sft = x & 7;
           gt.width = x2;
           gt.mask = (UINT8)((~0x7f) >> ((x2 - 1) & 7));
           do {
                   mask <<= 4;
                   for (pl=0; pl<4; pl++) {
                           mask >>= 1;
                           if (mask & 8) {
                                   gt.baseptr = mem + lio->draw.base + lioplaneadrs[pl];
                                   getvram(&gt, pat);
                                   i286_memstr_write(seg, off, pat, datacnt);
                                   off += datacnt;
                           }
                   }
                   gt.addr += 80;
           } while(--y2);
           lio->wait = size * 12;
           return(LIO_SUCCESS);
   }
   
   
   // ---- GPUT1
   
   REG8 lio_gput1(GLIO lio) {
   
           GPUT1   dat;
           LIOPUT  lput;
           UINT    leng;
           UINT    size;
   
           lio_updatedraw(lio);
           i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat));
           lput.x = (SINT16)LOADINTELWORD(dat.x);
           lput.y = (SINT16)LOADINTELWORD(dat.y);
           lput.off = (UINT16)(LOADINTELWORD(dat.off) + 4);
           lput.seg = LOADINTELWORD(dat.seg);
           lput.mode = dat.mode;
           leng = LOADINTELWORD(dat.leng);
           lput.width = i286_memword_read(lput.seg, lput.off - 4);
           lput.height = i286_memword_read(lput.seg, lput.off - 2);
           size = ((lput.width + 7) >> 3) * lput.height;
           if (leng < (size + 4)) {
                   return(LIO_ILLEGALFUNC);
           }
           if (leng < ((size * 3) + 4)) {
                   lput.sw = 0;
                   if (dat.colorsw) {
                           lput.fg = dat.fg;
                           lput.bg = dat.bg;
                   }
                   else {
                           lput.fg = lio->work.fgcolor;
                           lput.bg = lio->work.bgcolor;
                   }
           }
           else {
                   if (dat.colorsw) {
                           lput.sw = 0;
                           lput.fg = dat.fg;
                           lput.bg = dat.bg;
                   }
                   else {
                           lput.sw = 1;
                           lput.fg = 0x0f;
                           lput.bg = 0;
                   }
           }
           return(putsub(lio, &lput));
   }
   
   
   // ---- GPUT2
   
 BYTE lio_gput1(void) {  REG8 lio_gput2(GLIO lio) {
   
         MEMGPUT1        dat;          GPUT2   dat;
           LIOPUT  lput;
           UINT16  jis;
           REG16   size;
   
         i286_memstr_read(I286_DS, I286_BX, &dat, sizeof(dat));          lio_updatedraw(lio);
         return(0);          i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat));
           lput.x = (SINT16)LOADINTELWORD(dat.x);
           lput.y = (SINT16)LOADINTELWORD(dat.y);
           jis = LOADINTELWORD(dat.chr);
           if (jis & 0xff00) {
                   lput.off = 0x104e;
                   lput.seg = CPU_DS;
                   if (jis < 0x200) {                      // 1/4ANK
                           jis &= 0xff;
                   }
                   size = bios0x18_14(lput.seg, 0x104c, jis);
                   lput.width = (size & 0xff00) >> (8 - 3);
                   lput.height = (size & 0xff) << 3;
           }
           else {
                   return(0);
           }
           lput.mode = dat.mode;
           lput.sw = 0;
           if (dat.colorsw) {
                   lput.fg = dat.fg;
                   lput.bg = dat.bg;
           }
           else {
                   lput.fg = lio->work.fgcolor;
                   lput.bg = lio->work.bgcolor;
           }
           return(putsub(lio, &lput));
 }  }
   

Removed from v.1.1.1.1  
changed lines
  Added in v.1.10


RetroPC.NET-CVS <cvs@retropc.net>