home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / apa16 / apa16Hdwr.h < prev    next >
C/C++ Source or Header  |  1992-02-11  |  12KB  |  353 lines

  1. #ifndef HDWR_SEEN
  2. #define HDWR_SEEN 1
  3. /***********************************************************
  4.         Copyright IBM Corporation 1987,1988
  5.  
  6.                       All Rights Reserved
  7.  
  8. Permission to use, copy, modify, and distribute this software and its 
  9. documentation for any purpose and without fee is hereby granted, 
  10. provided that the above copyright notice appear in all copies and that
  11. both that copyright notice and this permission notice appear in 
  12. supporting documentation, and that the name of IBM not be
  13. used in advertising or publicity pertaining to distribution of the
  14. software without specific, written prior permission.  
  15.  
  16. IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  17. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  18. IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  19. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  21. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  22. SOFTWARE.
  23.  
  24. ******************************************************************/
  25. /* $Header: /afs/athena.mit.edu/astaff/project/x11r5/src/athena/ibm/apa16/RCS/apa16Hdwr.h,v 5.1 1992/02/12 00:32:01 jfc Exp $ */
  26. /* $Source: /afs/athena.mit.edu/astaff/project/x11r5/src/athena/ibm/apa16/RCS/apa16Hdwr.h,v $ */
  27.  
  28. #if !defined(lint) && defined(RCS_HDRS)
  29. static char *rcsidapa16hdwr = "$Id: apa16Hdwr.h,v 5.1 1992/02/12 00:32:01 jfc Exp $";
  30. #endif
  31.  
  32. #ifndef FALSE
  33. #define FALSE 0
  34. #endif
  35.  
  36. #ifndef TRUE
  37. #define TRUE 1
  38. #endif
  39.  
  40. typedef volatile unsigned short int * apa16MemoryPtr;
  41.  
  42. #define    APA16_BASE        (0xf4d80000)
  43. #define SCREEN_ADDR(x,y)    ((apa16MemoryPtr)(APA16_BASE+((y)*128)+(((x)&0x3ff)>>3)))
  44.  
  45. #define    APA16_WIDTH        1024
  46. #define    APA16_HEIGHT        768
  47.  
  48. /* The compiler optimizes better if these are in a structure, not
  49.    separate variables. */
  50. extern struct apa16Qvars {
  51.     int    apa16QVoffset;
  52.     int    apa16QVoverflow;
  53.     int    apa16QVmerge_mode_old;
  54. } apa16Qvars;
  55. #define    apa16Qoffset        apa16Qvars.apa16QVoffset
  56. #define    apa16Qoverflow        apa16Qvars.apa16QVoverflow
  57. #define    apa16Qmerge_mode_old    apa16Qvars.apa16QVmerge_mode_old
  58.  
  59. extern    int    apa16CheckQ();
  60.  
  61. extern    unsigned short int    apa16_rop2stype[];
  62. extern    unsigned short int    apa16_rop2logop[];
  63.  
  64. #define CURSOR_X    (*(apa16MemoryPtr)0xf4d9f800)
  65. #define CURSOR_Y    (*(apa16MemoryPtr)0xf4d9f802)
  66.  
  67. #define    MAXCURSORS        3
  68. #define CURSOR_AND_OFFSET    0
  69. #define CURSOR_XOR_OFFSET    48
  70. #define    CURSOR_WIDTH        48
  71. #define    CURSOR_HEIGHT        64
  72. #define CURSOR_AREA_TOP        784
  73. #define CURSOR_AREA_BOTTOM    (CURSOR_AREA_TOP + CURSOR_HEIGHT)
  74.  
  75. #define    STAGE_WIDTH        96 /* Allows 64 bit wide on any boundry < 32 */
  76. #define    STAGE_HEIGHT        CURSOR_HEIGHT
  77. #define    STAGE_X_OFFSET        (APA16_WIDTH - STAGE_WIDTH)
  78. #define STAGE_AREA_TOP        CURSOR_AREA_TOP
  79. #define STAGE_AREA_BOTTOM    (STAGE_AREA_TOP + STAGE_HEIGHT)
  80. #define APA16_STAGE_X        STAGE_X_OFFSET
  81. #define APA16_STAGE_Y        STAGE_AREA_TOP
  82.  
  83. #define ACTIVE_AND_AREA    SCREEN_ADDR(0, CURSOR_AREA_TOP)
  84. #define ACTIVE_XOR_AREA SCREEN_ADDR(CURSOR_XOR_OFFSET, CURSOR_AREA_TOP)
  85.  
  86. #define    FONT_TOP    848
  87. #define    FONT_BOTTOM    895    
  88.  
  89. #define CSR        (*(apa16MemoryPtr)0xf0000d12)
  90. #define    BLACK_ON_WHITE()    (CSR|=0x400)
  91. #define    WHITE_ON_BLACK()    (CSR&=~0x400)
  92. #define    TOGGLE_BACKGRND()    (CSR^=0x400)
  93.  
  94. #define    MR        (*(apa16MemoryPtr)0xf0000d10)
  95. #define MODE_SHADOW    (*(apa16MemoryPtr)0xf4d9f812)
  96. #define    SCANLINE    (*(apa16MemoryPtr)0xf4d9f808)
  97.  
  98. #define    MERGE_MODE_MASK    (0xff0f)
  99. #define    MERGE_MODE    (MODE_SHADOW&(~MERGE_MODE_MASK))
  100. #define    MERGE_AND    (0x10)
  101. #define    MERGE_BLACK    (0x20)
  102. #define    MERGE_AND_NOT    (0x80)    /* src & ~dst */
  103. #define    MERGE_COPY    (0x90)
  104. #define    MERGE_INVERT    (0xa0)
  105. #define    MERGE_WHITE    (0xb0)
  106. #define    MERGE_NAND    (0xe0)    /* ~src | ~dst */
  107. #define    BAD_LOGOP    (0xffff)
  108. #define    MR_DEFAULT    0x8090
  109.  
  110. #define    BIT_OFFSET_MASK    (0x000f)
  111. #define    BIT_OFFSET    (MODE_SHADOW&(~BIT_OFFSET_MASK))
  112. #define    SET_BIT_OFFSET(off)    (MR=(MODE_SHADOW&BIT_OFFSET_MASK)|(off))
  113.  
  114. #define SPTR_TO_QPTR(p)    (((unsigned)(p)>>1)&0xffff)
  115. #define QPTR_TO_SPTR(p)    ((apa16MemoryPtr)(0xf4d90000|((((unsigned)(p))<<1)&0xffff)))
  116.  
  117. #define QPTR_QUEUE_TOP    SPTR_TO_QPTR(QUEUE_TOP)
  118. #define    QPTR_QUEUE_BASE    SPTR_TO_QPTR(QUEUE_BASE)
  119. #define    QUEUE_TOP    ((apa16MemoryPtr)0xf4d9f6fe)
  120. #define    QUEUE_BASE    ((apa16MemoryPtr)0xf4d9c000)
  121. /* #define QUEUE_TOP    SCREEN_ADDR(APA16_WIDTH-1,1005) */
  122. /* #define QUEUE_BASE    SCREEN_ADDR(0,896) */
  123. #define QUEUE_SIZE    (QUEUE_TOP - QUEUE_BASE)
  124. #define    QUEUE_CNTR    (*(apa16MemoryPtr)0xf4d9f804)
  125. #define QUEUE_PTR    (*(apa16MemoryPtr)0xf4d9f806)
  126.  
  127. /*
  128.  * QUEUE_DANGER represents the number of instructions that can be
  129.  * pushed onto the queue without worrying.  This size is computed
  130.  * by hand, and if the size of the queue changes, this value must
  131.  * also be changed.  It is the value computed from:
  132.  *
  133.  *      min(max_queue_commands, queue_size/max_cmd_len)
  134.  */
  135. #define QUEUE_DANGER    1004
  136.  
  137. #define INCR_QUEUE_CNTR()       (*(apa16MemoryPtr)0xf0000d14=0)
  138. #define LOAD_QUEUE(rop,off)    (*(QUEUE_BASE+apa16Qoffset+(off))=(rop))
  139.  
  140. #define REG_LOAD(reg,val,off)    \
  141.     LOAD_QUEUE((((reg)<<12)&0xf000)|(val)&0x3ff,off)
  142.  
  143. #define    CMD_LOAD(cmd,off)    \
  144.     (LOAD_QUEUE(((cmd)|EXEC_MASK),off),INCR_QUEUE_CNTR())
  145.  
  146. #define    CMD_LOAD_NOEXEC(cmd,off) (LOAD_QUEUE((cmd),off),INCR_QUEUE_CNTR())
  147.  
  148. #define    CMD_MASK    0xfff0
  149. #define STYPE_MASK    0x000f
  150. #define EXEC_MASK    0x0800
  151.  
  152. #ifndef RROP_BLACK
  153. #define RROP_BLACK    GXclear
  154. #define RROP_WHITE    GXset
  155. #define RROP_NOP    GXnoop
  156. #define RROP_INVERT    GXinvert
  157. #endif
  158.  
  159. #define STYPE_BLACK        0x0000
  160. #define STYPE_WHITE        0x000f
  161. #define STYPE_RECT_INVERT    0x0009
  162. #define STYPE_INVERT        0x000a
  163. #define STYPE_NOP        0x0007
  164.  
  165. #define ROP_RECT_FILL        0xd2f0
  166. #define ROP_RECT_COPY        0xd300
  167. #define ROP_RECT_COPY_L90    0xd310
  168. #define ROP_RECT_COPY_R90    0xd320
  169. #define ROP_RECT_COPY_X180    0xd330
  170. #define ROP_RECT_COPY_Y180    0xd340
  171. #define ROP_VECTOR        0xd350
  172. #define ROP_NULL_VECTOR        0xd360
  173. #define    ROP_BRANCH        0xd3b0
  174. #define    ROP_VIDEO_ON        0xd3e0
  175. #define    ROP_VIDEO_OFF        0xd3f0
  176.  
  177.  
  178. /*
  179.  * SET_MERGE_MODE() takes effect immediately, so we must wait for the
  180.  * hardware queue to empty out.  It also appears that if we proceed
  181.  * processing after changing the Mode Register, that glitches can
  182.  * sometimes be observed.  For this reason, we wait until the
  183.  * Shadow Mode Register contains the new mode.
  184.  */
  185. #define    SET_MERGE_MODE(mode)                    \
  186.     {                            \
  187.         QUEUE_WAIT();                    \
  188.         if (apa16Qmerge_mode_old != (mode)) {        \
  189.         apa16Qmerge_mode_old = (mode);            \
  190.         (MR=(MODE_SHADOW&MERGE_MODE_MASK)|(mode));    \
  191.         }                            \
  192.     }
  193.  
  194. #define QUEUE_INIT()            \
  195.     {                \
  196.         apa16Qoffset=QUEUE_SIZE;    \
  197.         QUEUE_CNTR=0;        \
  198.         QUEUE_PTR=QPTR_QUEUE_TOP;    \
  199.     }
  200.  
  201. #define QUEUE_WAIT()    while (QUEUE_CNTR)
  202.  
  203. /*
  204.  * The CHECK_QUEUE() instruction pushes a new item onto the circular
  205.  * hardware queue.  The queue builds downwards, and when we approach
  206.  * the lower limit of the queue, we wrap back up to the top by pushing
  207.  * onto the queue the "jump" instruction pointing to the top of the
  208.  * stack.
  209.  *
  210.  * We have to be careful not to overflow the queue, but doing lots of
  211.  * memory lookups is not good, so we only do them if the QUEUE_CNTR is
  212.  * large enough to possibly overflow the queue.  Since this danger point
  213.  * is close to the maximum number of instructions that may be pushed onto
  214.  * the hardware queue, just play it safe and don't allow more than this
  215.  * danger point.  The danger point is 1005 instructions, and the maximum
  216.  * number of instructions is 1023.  The additional logic to allow an extra
  217.  * 18 instructions will probably hinder on the speed more than it is worth.
  218.  *
  219.  * The old tests to try accomodating the extra instructions, which did not
  220.  * quite work are shown below.  These instructions replaced the line
  221.  * that waits until QUEUE_CNTR < QUEUE_DANGER.
  222.  *
  223.  *    register int qc=QUEUE_CNTR,qd,qe;
  224.  * 
  225.  *    else if ((qc&=0x3ff) >= QUEUE_DANGER) {
  226.  *        while (((int)QUEUE_CNTR & 0x3ff) == 0x3ff) ;
  227.  *        while ((((qd = (int)(QUEUE_PTR - QPTR_QUEUE_BASE)) <=
  228.  *                 (qe = ((apa16Qoffset <= (off))                  
  229.  *                        ? QUEUE_SIZE : apa16Qoffset))) &&        
  230.  *                (qe-(off) < qd)) ||                              
  231.  *               ((apa16Qoffset <= (off)) && (qd <= (off)))) ;     
  232.  *    }                                                            
  233.  */
  234.  
  235. #define    CHECK_QUEUE(off,inst)                        \
  236.     {                                \
  237.         if (!QUEUE_CNTR) {QUEUE_INIT();}                \
  238.             else while ((QUEUE_CNTR & 0x3ff) >= QUEUE_DANGER) ;         \
  239.         if (apa16Qoffset-(off)<1) {                    \
  240.         LOAD_QUEUE(QPTR_QUEUE_TOP,0);                \
  241.         apa16Qoffset= QUEUE_SIZE;                \
  242.         }                                \
  243.         apa16Qoffset-=(off);                    \
  244.         (inst);                            \
  245.     }
  246.  
  247. #define    RESERVE_QUEUE(ninst)                        \
  248.     {                                \
  249.         if (!QUEUE_CNTR) {QUEUE_INIT();}                \
  250.             else while ((QUEUE_CNTR & 0x3ff) >= QUEUE_DANGER) ;         \
  251.         if (apa16Qoffset-(ninst)<1) {                \
  252.         LOAD_QUEUE(QPTR_QUEUE_TOP,0);                \
  253.         apa16Qoffset= QUEUE_SIZE;                \
  254.     }}
  255.  
  256. #define APA16_GET_CMD(cmd,rrop,out) \
  257.     if (((cmd)&CMD_MASK)==ROP_RECT_FILL) {\
  258.         (out)= ((cmd)&CMD_MASK)|\
  259.         (((rrop)==RROP_WHITE?STYPE_WHITE:\
  260.             ((rrop)==RROP_BLACK?STYPE_BLACK:\
  261.             ((rrop)==RROP_INVERT?\
  262.             STYPE_RECT_INVERT:\
  263.             STYPE_NOP)))&STYPE_MASK);\
  264.     }\
  265.     else if ((((cmd)&CMD_MASK)==ROP_VECTOR)||\
  266.          (((cmd)&CMD_MASK)==ROP_NULL_VECTOR)) {\
  267.         (out)= ((cmd)&CMD_MASK)|\
  268.         (((rrop)==RROP_WHITE?STYPE_WHITE:\
  269.             ((rrop)==RROP_BLACK?STYPE_BLACK:\
  270.             ((rrop)==RROP_INVERT?\
  271.             STYPE_INVERT:\
  272.             STYPE_NOP)))&STYPE_MASK);\
  273.     }\
  274.     else if ((((cmd)&CMD_MASK)==ROP_RECT_COPY)||\
  275.          (((cmd)&CMD_MASK)==ROP_RECT_COPY_L90)||\
  276.          (((cmd)&CMD_MASK)==ROP_RECT_COPY_R90)||\
  277.          (((cmd)&CMD_MASK)==ROP_RECT_COPY_X180)||\
  278.          (((cmd)&CMD_MASK)==ROP_RECT_COPY_Y180)) {\
  279.         (out)= ((cmd)&CMD_MASK)|(apa16_rop2stype[rrop&0xf]&STYPE_MASK);\
  280.     }\
  281.     else {\
  282.         ErrorF("WSGO! Unknown rasterop 0x%x\n",(cmd));\
  283.     }
  284.  
  285. #define    APA16_GET_CMD_VECTOR(cmd,rrop,out)                \
  286.     ((out)= ((cmd)&CMD_MASK)|(((rrop)==RROP_WHITE?STYPE_WHITE:    \
  287.           ((rrop)==RROP_BLACK?STYPE_BLACK:            \
  288.            ((rrop)==RROP_INVERT?STYPE_INVERT:STYPE_NOP)))&STYPE_MASK))
  289.  
  290.  
  291. #define    APA16_GET_CMD_FILL(rrop,out)                    \
  292.     (out) = (ROP_RECT_FILL|                        \
  293.          (((rrop)==RROP_WHITE ? STYPE_WHITE:            \
  294.            ((rrop)==RROP_BLACK ? STYPE_BLACK:            \
  295.             ((rrop)==RROP_INVERT ? STYPE_RECT_INVERT : STYPE_NOP)))&STYPE_MASK));
  296.  
  297. #define    APA16_GET_CMD_COPY(cmd,rrop,out)                \
  298.     (out) = ((cmd)&CMD_MASK)|(apa16_rop2stype[rrop&0xf]&STYPE_MASK);
  299.  
  300. #define FILL_RECT(cmd,x,y,dx,dy)    \
  301.         CHECK_QUEUE(5,(REG_LOAD(7,x,5),REG_LOAD(6,y,4),\
  302.                 REG_LOAD(9,dx,3),REG_LOAD(8,dy,2),\
  303.                 CMD_LOAD((cmd),1)))
  304.  
  305. #define    FILL_RECT_NOCHECK(cmd,x,y,dx,dy)            \
  306.         apa16Qoffset -= 5;                \
  307.         (REG_LOAD(7,x,5),REG_LOAD(6,y,4),        \
  308.                 REG_LOAD(9,dx,3),REG_LOAD(8,dy,2),    \
  309.                 CMD_LOAD_NOEXEC((cmd),1))
  310.  
  311. #define COPY_RECT(cmd,xd,yd,xs,ys,dx,dy)    \
  312.         CHECK_QUEUE(7,(REG_LOAD(7,xd,7),REG_LOAD(0xA,yd,6),\
  313.                 REG_LOAD(5,xs,5),REG_LOAD(4,ys,4),\
  314.                 REG_LOAD(9,dx,3),REG_LOAD(0,dy,2),\
  315.                 CMD_LOAD((cmd),1)))
  316.  
  317. /* Setup for n copy rect operations with destination y = yd. */
  318. #define    COPY_RECT_SETY(n,yd)    \
  319.     if (!QUEUE_CNTR) {QUEUE_INIT();}                \
  320.     else { while (6 * (n) + (QUEUE_CNTR & 0x3ff) >= QUEUE_DANGER);    \
  321.            if (apa16Qoffset-6*(n)<2) {LOAD_QUEUE(QPTR_QUEUE_TOP,0);    \
  322.                     apa16Qoffset= QUEUE_SIZE;}}    \
  323.     apa16Qoffset--;REG_LOAD(10,yd,1);
  324.  
  325. /* Use this after calling CHECK_QUEUE and REG_LOAD(10,y). */
  326. #define    COPY_RECT_CONT(cmd,xd,xs,ys,dx,dy)    \
  327.         apa16Qoffset -= 6;        \
  328.         REG_LOAD(7,xd,6),REG_LOAD(5,xs,5),REG_LOAD(4,ys,4),\
  329.         REG_LOAD(9,dx,3),REG_LOAD(0,dy,2),CMD_LOAD_NOEXEC(cmd,1)
  330.  
  331. /* Use this after calling CHECK_QUEUE. */
  332. #define    COPY_RECT_NOCHECK(cmd,xd,yd,xs,ys,dx,dy)    \
  333.         apa16Qoffset -= 7;            \
  334.         REG_LOAD(7,xd,7),REG_LOAD(10,yd,6),    \
  335.         REG_LOAD(5,xs,5),REG_LOAD(4,ys,4),    \
  336.         REG_LOAD(9,dx,3),REG_LOAD(0,dy,2),CMD_LOAD_NOEXEC((cmd),1)
  337.  
  338. #define DRAW_VECTOR(cmd,fx,fy,tx,ty)    \
  339.         CHECK_QUEUE(5,(REG_LOAD(1,fx,5),REG_LOAD(0,fy,4),\
  340.                 REG_LOAD(5,tx,3),REG_LOAD(6,ty,2),\
  341.                 CMD_LOAD((cmd),1)))
  342.  
  343. #define POLY_VECTOR(cmd,tx,ty) \
  344.         CHECK_QUEUE(3,(REG_LOAD(5,tx,3),REG_LOAD(6,ty,2),\
  345.                 CMD_LOAD((cmd),1)))
  346.  
  347. #define VIDEO_ON() \
  348.         CHECK_QUEUE(1,(CMD_LOAD(ROP_VIDEO_ON,1)))
  349.  
  350. #define VIDEO_OFF() \
  351.         CHECK_QUEUE(1,(CMD_LOAD(ROP_VIDEO_OFF,1)))
  352. #endif /* ndef HDWR_SEEN */
  353.