File: dos\tplus.c

    1 /* TPLUS.C, (C) 1991 The Yankee Programmer
    2    All Rights Reserved.
    3 
    4    This code may be distributed only when bundled with the Fractint
    5    source code.
    6 
    7    Mark C. Peterson
    8    The Yankee Programmer
    9    405-C Queen Street, Suite #181
   10    Southington, CT 06489
   11    (203) 276-9721
   12 
   13 */
   14 
   15 #include <conio.h>
   16 #include <string.h>
   17 
   18   /* see Fractint.c for a description of the "include"  hierarchy */
   19 #include "port.h"
   20 #include "prototyp.h"
   21 #include "tplus.h"
   22 
   23 struct TPWrite far WriteOffsets = {
   24       0,       1,       2,       3,       0x400,   0x401,      0x402,
   25       0x403,   0x800,   0x801,   0x802,   0x803,   0xc00,      0xc01,
   26       0xc02,   0xc03
   27 };
   28 
   29 struct TPRead far ReadOffsets = {
   30       0,                2,       3,       0x400,   0x401,      0x402,
   31       0x403,   0x800,   0x801,   0x802,   0x803,   0xc00,      0xc01,
   32       0xc02,   0xc03
   33 };
   34 
   35 struct _BOARD far TPlus;
   36 int TPlusErr = 0;
   37 
   38 void WriteTPWord(unsigned Register, unsigned Number) {
   39    OUTPORTB(TPlus.Write.INDIRECT, Register);
   40    OUTPORTW(TPlus.Write.WBL, Number);
   41 }
   42 
   43 void WriteTPByte(unsigned Register, unsigned Number) {
   44    OUTPORTB(TPlus.Write.INDIRECT, Register);
   45    OUTPORTB(TPlus.Write.WBL, Number);
   46 }
   47 
   48 unsigned ReadTPWord(unsigned Register) {
   49    OUTPORTB(TPlus.Write.INDIRECT, Register);
   50    return(INPORTW(TPlus.Read.RBL));
   51 }
   52 
   53 BYTE ReadTPByte(unsigned Register) {
   54    OUTPORTB(TPlus.Write.INDIRECT, Register);
   55    return((BYTE)INPORTB(TPlus.Read.RBL));
   56 }
   57 
   58 void DisableMemory(void) {
   59    unsigned Mode1;
   60 
   61    Mode1 = INPORTB(TPlus.Read.MODE1);
   62    Mode1 &= 0xfe;
   63    OUTPORTB(TPlus.Write.MODE1, Mode1);
   64 }
   65 
   66 void EnableMemory(void) {
   67    unsigned Mode1;
   68 
   69    Mode1 = INPORTB(TPlus.Read.MODE1);
   70    Mode1 |= 1;
   71    OUTPORTB(TPlus.Write.MODE1, Mode1);
   72 }
   73 
   74 struct TPLUS_IO {
   75    unsigned Cmd;
   76    int Initx, Finalx, Inity, Finaly, Destx, Desty;
   77    unsigned long Color;
   78    unsigned RegsOffset, RegsSegment, RegListOffset, RegListSegment,
   79             BoardNumber, StructSize;
   80 } far TPlusIO;
   81 
   82 /* TARGAP.SYS Commands */
   83 #define READALL    0
   84 #define WRITEALL   0
   85 #define NUMBOARDS  3
   86 #define FILLBLOCK  4
   87 #define GRABFIELD  4
   88 #define RESET      5
   89 #define GRABFRAME  5
   90 #define WAITFORVB  6
   91 #define SETBOARD   8
   92 #define IOBASE     9
   93 
   94 /* DOS IO Commands */
   95 #define DOS_READ   0x4402
   96 #define DOS_WRITE  0x4403
   97 
   98 int hTPlus = -1;
   99 unsigned NumTPlus = 0;
  100 
  101 int TargapSys(int Command, unsigned DOS) {
  102    struct TPLUS_IO far *IOPtr;
  103    unsigned far *RegPtr;
  104    union REGS r;
  105    struct SREGS s;
  106 
  107    if(hTPlus != -1) {
  108       r.x.ax = DOS;
  109       r.x.bx = hTPlus;
  110       r.x.cx = sizeof(TPlusIO);
  111       IOPtr = &TPlusIO;
  112       RegPtr = TPlus.Reg;
  113       r.x.dx = FP_OFF(IOPtr);
  114       s.ds = FP_SEG(IOPtr);
  115       TPlusIO.Cmd = Command;
  116       TPlusIO.StructSize = sizeof(TPlus.Reg);
  117       TPlusIO.RegsOffset = FP_OFF(RegPtr);
  118       TPlusIO.RegsSegment = FP_SEG(RegPtr);
  119       intdosx(&r, &r, &s);
  120       return(!r.x.cflag);
  121    }
  122    return(0);
  123 }
  124 
  125 int _SetBoard(int BoardNumber) {
  126    TPlusIO.BoardNumber = BoardNumber;
  127    return(TargapSys(SETBOARD, DOS_WRITE));
  128 }
  129 
  130 int TPlusLUT(BYTE far *LUTData, unsigned Index, unsigned Number,
  131              unsigned DosFlag)
  132 {
  133    struct TPLUS_IO far *IOPtr;
  134    union REGS r;
  135    struct SREGS s;
  136 
  137    if(hTPlus != -1) {
  138       r.x.ax = DosFlag;
  139       r.x.bx = hTPlus;
  140       r.x.cx = sizeof(TPlusIO);
  141       IOPtr = &TPlusIO;
  142       r.x.dx = FP_OFF(IOPtr);
  143       s.ds = FP_SEG(IOPtr);
  144       TPlusIO.Cmd = 9;
  145       TPlusIO.StructSize = sizeof(TPlus.Reg);
  146       TPlusIO.RegsOffset = FP_OFF(LUTData);
  147       TPlusIO.RegsSegment = FP_SEG(LUTData);
  148       TPlusIO.BoardNumber = Number;
  149       TPlusIO.RegListOffset = Index;
  150       intdosx(&r, &r, &s);
  151       return(!r.x.cflag);
  152    }
  153    return(0);
  154 }
  155 
  156 int SetVGA_LUT(void) {
  157    char PathName[FILE_MAX_PATH];
  158    FILE *Data = NULL;
  159    BYTE LUTData[256 * 3];
  160 
  161    findpath("tplus.dat", PathName);
  162    if(PathName[0]) {
  163       if((Data = fopen(PathName, "rb")) != NULL) {
  164          if(!fseek(Data, 16L << 8, SEEK_SET)) {
  165             if(fread(LUTData, 1, sizeof(LUTData), Data) == sizeof(LUTData)) {
  166                fclose(Data);
  167                return(TPlusLUT(LUTData, 0, sizeof(LUTData), DOS_WRITE));
  168             }
  169          }
  170       }
  171    }
  172    if(Data != NULL)
  173       fclose(Data);
  174    return(0);
  175 }
  176 
  177 int SetColorDepth(int Depth) {
  178    if(TPlus.Reg[HIRES] && Depth == 4)
  179       Depth = 2;
  180    switch(Depth) {
  181       case 1:
  182          if(TPlus.Reg[XDOTS] > 512) {
  183             TPlus.Reg[PERM] = 1;
  184             TPlus.Reg[BYCAP] = 3;
  185             TPlus.RowBytes = 10;
  186          }
  187          else {
  188             TPlus.Reg[PERM] = 0;
  189             TPlus.Reg[BYCAP] = 1;
  190             TPlus.RowBytes = 9;
  191          }
  192          TPlus.Reg[BUFFPORTSRC] = 0;
  193          TPlus.Reg[CM1] = 0;
  194          TPlus.Reg[CM2] = 0;
  195          TPlus.Reg[DEPTH] = 1;
  196          TPlus.Reg[LIVE8] = 1;
  197          TPlus.Reg[DISPMODE] = 0;
  198          TPlus.Reg[LIVEPORTSRC] = 1;
  199          TPlus.Reg[LUTBYPASS] = 0;
  200          break;
  201       case 2:
  202          if(TPlus.Reg[XDOTS] > 512) {
  203             TPlus.Reg[PERM] = 3;
  204             TPlus.Reg[BYCAP] = 15;
  205             TPlus.Reg[CM2] = 1;
  206             TPlus.RowBytes = 11;
  207          }
  208          else {
  209             TPlus.Reg[PERM] = 1;
  210             TPlus.Reg[BYCAP] = 3;
  211             TPlus.Reg[CM2] = 0;
  212             TPlus.RowBytes = 10;
  213          }
  214          TPlus.Reg[BUFFPORTSRC] = 1;
  215          TPlus.Reg[CM1] = 0;
  216          TPlus.Reg[DEPTH] = 2;
  217          TPlus.Reg[LIVE8] = 0;
  218          TPlus.Reg[DISPMODE] = 0;
  219          TPlus.Reg[LIVEPORTSRC] = 1;
  220          TPlus.Reg[LUTBYPASS] = 1;
  221          break;
  222       case 3:
  223       case 4:
  224          TPlus.Reg[PERM] = (Depth == 3) ? 2 : 3;
  225          TPlus.Reg[BYCAP] = 0xf;
  226          TPlus.Reg[BUFFPORTSRC] = 3;
  227          TPlus.Reg[CM1] = 1;
  228          TPlus.Reg[CM2] = 1;
  229          TPlus.Reg[DEPTH] = 4;
  230          TPlus.Reg[LIVE8] = 0;
  231          TPlus.Reg[DISPMODE] = 0;
  232          TPlus.Reg[LIVEPORTSRC] = 1;
  233          TPlus.Reg[LUTBYPASS] = 1;
  234          TPlus.RowBytes = 11;
  235          break;
  236       default:
  237          return(0);
  238    }
  239    TPlus.Plot = WriteTPlusBankedPixel;
  240    TPlus.GetColor = ReadTPlusBankedPixel;
  241    TPlus.Reg[LIVEMIXSRC] = 0;
  242    TPlus.Reg[CM3] = 1;
  243    TPlus.RowsPerBank = 16 - TPlus.RowBytes;
  244    if(TargapSys(WRITEALL, DOS_WRITE)) {
  245       if(Depth == 1)
  246          SetVGA_LUT();
  247       if(TPlus.ClearScreen)
  248          ClearTPlusScreen();
  249       TargapSys(READALL, DOS_READ);
  250       return(Depth);
  251    }
  252    return(0);
  253 }
  254 
  255 int SetBoard(int BoardNumber) {
  256    unsigned ioBase, n;
  257    unsigned long MemBase;
  258 
  259    if(TPlus.ThisBoard != -1)
  260       DisableMemory();
  261    if(!_SetBoard(BoardNumber))
  262       return(0);
  263    if(!TargapSys(READALL, DOS_READ))
  264       return(0);
  265    TPlus.VerPan       = TPlus.Reg[VPAN];
  266    TPlus.HorPan       = TPlus.Reg[HPAN];
  267    TPlus.Top          = TPlus.Reg[TOP];
  268    TPlus.Bottom       = TPlus.Reg[BOT];
  269    TPlus.Bank64k      = 0xffff;                 /* Force a bank switch */
  270 
  271    MemBase        = TPlus.Reg[MEM_BASE];
  272    MemBase += (TPlus.Reg[MEM_MAP] != 3) ? 8 : 0;
  273    TPlus.Screen = (BYTE far *)(MemBase << 28);
  274 
  275    if(!TargapSys(IOBASE, DOS_READ))
  276       return(0);
  277    ioBase = TPlusIO.BoardNumber;
  278    TPlus.Read = ReadOffsets;
  279    TPlus.Write = WriteOffsets;
  280    for(n = 0; n < sizeof(TPlus.Read) / sizeof(unsigned); n++)
  281       ((unsigned far *)&(TPlus.Read))[n] += ioBase;
  282    for(n = 0; n < sizeof(TPlus.Write) / sizeof(unsigned); n++)
  283       ((unsigned far *)&(TPlus.Write))[n] += ioBase;
  284 
  285    EnableMemory();
  286    return(1);
  287 }
  288 
  289 int ResetBoard(int BoardNumber) {
  290    int CurrBoard, Status = 0;
  291 
  292    CurrBoard = TPlus.ThisBoard;
  293    if(_SetBoard(BoardNumber))
  294       Status = TargapSys(RESET, DOS_WRITE);
  295    if(CurrBoard > 0)
  296       _SetBoard(CurrBoard);
  297    return(Status);
  298 }
  299 
  300 #include <fcntl.h>
  301 #include <io.h>
  302 
  303 int CheckForTPlus(void) {
  304    unsigned n;
  305 
  306    if((hTPlus = open("TARGPLUS", O_RDWR | O_BINARY )) != -1) {
  307       if(!TargapSys(NUMBOARDS, DOS_READ))
  308          return(0);
  309       NumTPlus = TPlusIO.BoardNumber;
  310       TPlus.ThisBoard = -1;
  311       TPlus.ClearScreen = 1;
  312       for(n = 0; n < NumTPlus; n++)
  313          if(!ResetBoard(n))
  314             return(0);
  315       if(SetBoard(0))
  316          return(1);
  317    }
  318    return(0);
  319 }
  320 
  321 int SetTPlusMode(int Mode, int NotIntFlag, int Depth, int Zoom) {
  322    unsigned n;
  323    char PathName[FILE_MAX_PATH];
  324    FILE *Data = NULL;
  325    unsigned NewRegs[128];
  326 
  327    findpath("tplus.dat", PathName);
  328    if(PathName[0]) {
  329       if((Data = fopen(PathName, "rb")) != NULL) {
  330          if(!fseek(Data, (long)Mode << 8, SEEK_SET)) {
  331             if(fread(NewRegs, 1, 256, Data) == 256) {
  332                fclose(Data);
  333                NewRegs[PE] = TPlus.Reg[PE];
  334                NewRegs[OVLE] = TPlus.Reg[OVLE];
  335                NewRegs[RGB] = TPlus.Reg[RGB];
  336                NewRegs[SVIDEO] = TPlus.Reg[SVIDEO];
  337                NewRegs[DAC567DATA] = TPlus.Reg[DAC567DATA];
  338                NewRegs[VGASRC] = TPlus.Reg[VGASRC];
  339                for(n = 0; n < 128; n++)
  340                   TPlus.Reg[n] = NewRegs[n];
  341                if(TPlus.Reg[VTOP + 1] == 0xffff)
  342                   TPlus.Reg[NOT_INT] = 0;
  343                else if(TPlus.Reg[VTOP] == 0xffff && !NotIntFlag) {
  344                   TPlusErr = 1;
  345                   return(0);
  346                }
  347                else
  348                   TPlus.Reg[NOT_INT] = NotIntFlag;
  349                TPlus.xdots = TPlus.Reg[XDOTS];
  350                TPlus.ydots = TPlus.Reg[YDOTS];
  351                if(Zoom) {
  352                   TPlus.Reg[ZOOM] = Zoom;
  353                   TPlus.xdots >>= Zoom;
  354                   TPlus.ydots >>= Zoom;
  355                }
  356                return(SetColorDepth(Depth));
  357             }
  358          }
  359       }
  360    }
  361    if(Data != NULL)
  362       fclose(Data);
  363    return(0);
  364 }
  365 
  366 int FillTPlusRegion(unsigned x, unsigned y, unsigned xdots, unsigned ydots,
  367                unsigned long Color) {
  368    int Status = 0;
  369 
  370    TPlusIO.Initx = x;
  371    TPlusIO.Inity = TPlus.Reg[YDOTS] - (y + ydots) - 2;
  372    TPlusIO.Finalx = x + xdots - 1;
  373    TPlusIO.Finaly = TPlus.Reg[YDOTS] - y - 1;
  374    TPlusIO.Color = Color;
  375    Status = TargapSys(FILLBLOCK, DOS_WRITE);
  376    EnableMemory();
  377    return(Status);
  378 }
  379 
  380 void BlankScreen(unsigned long Color) {
  381    unsigned BufferPort;
  382 
  383    OUTPORTW(TPlus.Write.COLOR0, ((unsigned*)&Color)[0]);
  384    OUTPORTB(TPlus.Write.COLOR2, ((unsigned*)&Color)[1]);
  385    OUTPORTB(TPlus.Write.COLOR3, 0xff);
  386    BufferPort = ReadTPByte(0xe9);
  387    BufferPort |= 3;
  388    WriteTPByte(0xe9, BufferPort);
  389 }
  390 
  391 void UnBlankScreen(void) {
  392    unsigned BufferPort;
  393 
  394    BufferPort = ReadTPByte(0xe9);
  395    BufferPort &= 0xfe;
  396    WriteTPByte(0xe9, BufferPort);
  397 }
  398 
  399 void EnableOverlayCapture(void) {
  400    unsigned Mode2;
  401 
  402    Mode2 = INPORTB(TPlus.Read.MODE2);
  403    Mode2 |= (1 << 6);
  404    Mode2 &= (0xff ^ (3 << 4));
  405    Mode2 |= (1 << 5);
  406    OUTPORTB(TPlus.Write.MODE2, Mode2);
  407 }
  408 
  409 void DisableOverlayCapture(void) {
  410    unsigned Mode2;
  411 
  412    Mode2 = INPORTB(TPlus.Read.MODE2);
  413    Mode2 &= (0xff ^ (7 << 4));
  414    OUTPORTB(TPlus.Write.MODE2, Mode2);
  415 }
  416 
  417 void ClearTPlusScreen(void) {
  418    BlankScreen(0L);
  419    EnableOverlayCapture();
  420    TargapSys(WAITFORVB, DOS_READ);
  421    TargapSys(WAITFORVB, DOS_READ);
  422    TargapSys(WAITFORVB, DOS_READ);
  423    DisableOverlayCapture();
  424    UnBlankScreen();
  425 }
  426 
  427 static struct {
  428    unsigned xdots, ydots, Template, Zoom, Depth;
  429 } far ModeTable[] = {
  430    {512, 400, 0,  0, 4},
  431    {512, 476, 1,  0, 4},
  432    {512, 486, 2,  0, 4},
  433    {512, 576, 3,  0, 4},
  434    {640, 480, 4,  0, 2},
  435    {648, 486, 5,  0, 2},
  436    {720, 486, 6,  0, 2},
  437    {720, 576, 7,  0, 2},
  438    {756, 486, 8,  0, 2},
  439    {768, 576, 9,  0, 2},
  440    {800, 600, 10, 0, 2},
  441    {1024,768, 11, 0, 2},
  442    {640, 400, 13, 0, 2},
  443    {320, 200, 13, 1, 2},
  444    {512, 496, 14, 0, 4},
  445    {640, 496, 15, 0, 2}
  446 };
  447 
  448 static unsigned TableSize = (sizeof(ModeTable) / sizeof(ModeTable[0]));
  449 
  450 int MatchTPlusMode(unsigned xdots, unsigned ydots, unsigned MaxColorRes,
  451                    unsigned PixelZoom, unsigned NonInterlaced) {
  452    unsigned n, Depth;
  453 
  454    for(n = 0; n < TableSize; n++) {
  455       if(ModeTable[n].xdots == xdots && ModeTable[n].ydots == ydots)
  456          break;
  457    }
  458    if(n < TableSize) {
  459       if(ModeTable[n].Zoom)
  460          PixelZoom += ModeTable[n].Zoom;
  461       if(PixelZoom > 4)
  462          PixelZoom = 4;
  463       switch(MaxColorRes) {
  464          case 24:
  465             Depth = 4;
  466             break;
  467          case 16:
  468             Depth = 2;
  469             break;
  470          case 8:
  471          default:
  472             Depth = 1;
  473             break;
  474       }
  475       if(ModeTable[n].Depth < Depth)
  476          Depth = ModeTable[n].Depth;
  477       return(SetTPlusMode(ModeTable[n].Template, NonInterlaced, Depth,
  478              PixelZoom));
  479    }
  480    return(0);
  481 }
  482 
  483 void TPlusZoom(int Zoom) {
  484    unsigned Mode2;
  485 
  486    Zoom &= 3;
  487    Mode2 = INPORTB(TPlus.Read.MODE2);
  488    Mode2 &= (0xff ^ (3 << 2));
  489    Mode2 |= (Zoom << 2);
  490    OUTPORTB(TPlus.Write.MODE2, Mode2);
  491 }
  492