Annotation of tme/machine/sun/sun-cgsix.c, revision 1.1.1.1

1.1       root        1: /* $Id: sun-cgsix.c,v 1.3 2010/06/05 19:16:12 fredette Exp $ */
                      2: 
                      3: /* machine/sun/sun-cgsix.c - Sun cgsix emulation: */
                      4: 
                      5: /*
                      6:  * Copyright (c) 2009 Fredette
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *      This product includes software developed by Matt Fredette.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     25:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     26:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     27:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     28:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     29:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     31:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     32:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     33:  * POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35: 
                     36: #include <tme/common.h>
                     37: _TME_RCSID("$Id: sun-cgsix.c,v 1.3 2010/06/05 19:16:12 fredette Exp $");
                     38: 
                     39: /* includes: */
                     40: #include <tme/machine/sun.h>
                     41: #include <tme/generic/bus-device.h>
                     42: #include <tme/generic/fb.h>
                     43: #include "sun-fb.h"
                     44: 
                     45: /* macros: */
                     46: 
                     47: /* cgsix types: */
                     48: #define TME_SUNCG6_TYPE_NULL           (0)
                     49: #define TME_SUNCG6_TYPE_501_2325       (1)
                     50: 
                     51: /* register subregions: */
                     52: #define tme_suncg6_bus_subregion_p4 tme_suncg6_sunfb.tme_sunfb_bus_subregion_regs
                     53: #define tme_suncg6_bus_handler_p4 tme_suncg6_sunfb.tme_sunfb_bus_handler_regs
                     54: #define tme_suncg6_bus_subregion_fbc tme_suncg6_sunfb.tme_sunfb_bus_subregions[1]
                     55: #define tme_suncg6_bus_handler_fbc tme_suncg6_sunfb.tme_sunfb_bus_handlers[1]
                     56: #define tme_suncg6_bus_subregion_dac tme_suncg6_sunfb.tme_sunfb_bus_subregions[2]
                     57: #define tme_suncg6_bus_handler_dac tme_suncg6_sunfb.tme_sunfb_bus_handlers[2]
                     58: #define tme_suncg6_bus_subregion_fhc_thc tme_suncg6_sunfb.tme_sunfb_bus_subregions[4]
                     59: #define tme_suncg6_bus_handler_fhc_thc tme_suncg6_sunfb.tme_sunfb_bus_handlers[4]
                     60: #define tme_suncg6_bus_subregion_tec tme_suncg6_sunfb.tme_sunfb_bus_subregions[3]
                     61: #define tme_suncg6_bus_handler_tec tme_suncg6_sunfb.tme_sunfb_bus_handlers[3]
                     62: #define tme_suncg6_bus_subregion_alt tme_suncg6_sunfb.tme_sunfb_bus_subregions[6]
                     63: #define tme_suncg6_bus_handler_alt tme_suncg6_sunfb.tme_sunfb_bus_handlers[6]
                     64: 
                     65: /* this converts a group member to a register offset: */
                     66: #define _TME_SUNCG6_REG_X(module_cap, module, n, x)            \
                     67:   (_TME_CONCAT4(TME_SUNCG6_REG_,module_cap,_GROUP,n)           \
                     68:    + ((tme_uint8_t *) &((struct tme_suncg6 *) 0)               \
                     69:       ->_TME_CONCAT4(tme_suncg6_,module,_group,n)              \
                     70:       ._TME_CONCAT4(tme_suncg6_,module,_,x))                   \
                     71:    - ((tme_uint8_t *) &((struct tme_suncg6 *) 0)               \
                     72:       ->_TME_CONCAT4(tme_suncg6_,module,_group,n)))
                     73: 
                     74: /* this expands part of a large ternary expression that converts a
                     75:    register address into pointer to a register: */
                     76: #define TME_SUNCG6_REG_POINTER(suncg6, reg, module_cap, module, n)\
                     77:   (((reg)                                                      \
                     78:     >= _TME_CONCAT4(TME_SUNCG6_REG_,module_cap,_GROUP,n))      \
                     79:    && ((reg)                                                   \
                     80:        < (_TME_CONCAT4(TME_SUNCG6_REG_,module_cap,_GROUP,n)    \
                     81:          + sizeof((suncg6)                                     \
                     82:                   ->_TME_CONCAT4(tme_suncg6_,module,_group,n)))))\
                     83:   ? (((tme_suncg6_reg_t *)                                     \
                     84:       &((suncg6)                                               \
                     85:        ->_TME_CONCAT4(tme_suncg6_,module,_group,n)))           \
                     86:      + (((reg)                                                 \
                     87:         - _TME_CONCAT4(TME_SUNCG6_REG_,module_cap,_GROUP,n))   \
                     88:        / sizeof(tme_suncg6_reg_t)))
                     89:  
                     90: /* some register offsets and sizes: */
                     91: #define TME_SUNCG6_REG_DAC                     (0x200000)
                     92: #define TME_SUNCG6_REG_ALT                     (0x280000)
                     93: #define TME_SUNCG6_SIZ_ALT                     (0x1000)
                     94: #define TME_SUNCG6_REG_THC(n,x)                        _TME_SUNCG6_REG_X(THC,thc,n,x)
                     95: #define TME_SUNCG6_SIZ_THC                     (0x1000)
                     96: #define TME_SUNCG6_REG_FBC(n,x)                        _TME_SUNCG6_REG_X(FBC,fbc,n,x)
                     97: #define TME_SUNCG6_REG_TEC(n,x)                        _TME_SUNCG6_REG_X(TEC,tec,n,x)
                     98: #define TME_SUNCG6_TEC_SIZE                    (0x1000)
                     99: 
                    100: /* the FHC register: */
                    101: #define        TME_SUNCG6_FHC_ID_MASK                  (0xff000000)
                    102: #define        TME_SUNCG6_FHC_REVISION_MASK            (0x00f00000)
                    103: #define        TME_SUNCG6_FHC_DISABLE_FROP             (0x00080000)
                    104: #define        TME_SUNCG6_FHC_DISABLE_ROW              (0x00040000)
                    105: #define        TME_SUNCG6_FHC_DISABLE_SRC              (0x00020000)
                    106: #define        TME_SUNCG6_FHC_DISABLE_DST              (0x00010000)
                    107: #define        TME_SUNCG6_FHC_RESET                    (0x00008000)
                    108: #define        TME_SUNCG6_FHC_ENDIAN_LITTLE            (0x00002000)
                    109: #define        TME_SUNCG6_FHC_SIZE_MASK                (0x00001800)
                    110: #define         TME_SUNCG6_FHC_SIZE_1024_768            (0x00000000)
                    111: #define         TME_SUNCG6_FHC_SIZE_1152_900            (0x00000800)
                    112: #define         TME_SUNCG6_FHC_SIZE_1280_1024           (0x00001000)
                    113: #define         TME_SUNCG6_FHC_SIZE_1600_1280           (0x00001800)
                    114: #define        TME_SUNCG6_FHC_CPU_MASK                 (0x00000600)
                    115: #define         TME_SUNCG6_FHC_CPU_SPARC                (0x00000000)
                    116: #define         TME_SUNCG6_FHC_CPU_68K                  (0x00000200)
                    117: #define         TME_SUNCG6_FHC_CPU_IA32                 (0x00000400)
                    118: #define        TME_SUNCG6_FHC_TEST                     (0x00000100)
                    119: #define        TME_SUNCG6_FHC_TESTX_MASK               (0x000000f0)
                    120: #define        TME_SUNCG6_FHC_TESTY_MASK               (0x0000000f)
                    121: 
                    122: /* the THC miscellaneous register: */
                    123: #define        TME_SUNCG6_THC_MISC_UNKNOWN_20          (0xfff00000)
                    124: #define        TME_SUNCG6_THC_MISC_REVISION_MASK       (0x000f0000)
                    125: #define        TME_SUNCG6_THC_MISC_UNKNOWN_13          (0x0000e000)
                    126: #define        TME_SUNCG6_THC_MISC_RESET               (0x00001000)
                    127: #define        TME_SUNCG6_THC_MISC_UNKNOWN_11          (0x00000800)
                    128: #define        TME_SUNCG6_THC_MISC_ENABLE_VIDEO        (0x00000400)
                    129: #define        TME_SUNCG6_THC_MISC_SYNC                (0x00000200)
                    130: #define        TME_SUNCG6_THC_MISC_VSYNC               (0x00000100)
                    131: #define        TME_SUNCG6_THC_MISC_ENABLE_SYNC         (0x00000080)
                    132: #define        TME_SUNCG6_THC_MISC_CURSOR_RESOLUTION   (0x00000040)
                    133: #define        TME_SUNCG6_THC_MISC_INT_ENABLE          (0x00000020)
                    134: #define        TME_SUNCG6_THC_MISC_INT_ACTIVE          (0x00000010)
                    135: #define        TME_SUNCG6_THC_MISC_UNKNOWN_0           (0x0000000f)
                    136: 
                    137: /* the FBC rasterop register: */
                    138: #define TME_SUNCG6_FBC_RASTEROP_PLANE_ONES     (0x80000000)
                    139: #define TME_SUNCG6_FBC_RASTEROP_PLANE_ZEROES   (0x40000000)
                    140: #define TME_SUNCG6_FBC_RASTEROP_PIXEL_ONES     (0x20000000)
                    141: #define TME_SUNCG6_FBC_RASTEROP_PIXEL_ZEROES   (0x10000000)
                    142: #define TME_SUNCG6_FBC_RASTEROP_PATTERN_ONES   (0x08000000)
                    143: #define TME_SUNCG6_FBC_RASTEROP_PATTERN_ZEROES (0x04000000)
                    144: #define TME_SUNCG6_FBC_RASTEROP_POLYG_NONOVERLAP (0x02000000)
                    145: #define TME_SUNCG6_FBC_RASTEROP_POLYG_OVERLAP  (0x01000000)
                    146: #define TME_SUNCG6_FBC_RASTEROP_ATTR_SUPP      (0x00800000)
                    147: #define TME_SUNCG6_FBC_RASTEROP_ATTR_UNSUPP    (0x00400000)
                    148: #define TME_SUNCG6_FBC_RASTEROP_RAST_BOOL      (0x00000000)
                    149: #define TME_SUNCG6_FBC_RASTEROP_RAST_LINEAR    (0x00020000)
                    150: #define TME_SUNCG6_FBC_RASTEROP_PLOT_PLOT      (0x00000000)
                    151: #define TME_SUNCG6_FBC_RASTEROP_PLOT_UNPLOT    (0x00010000)
                    152: #define TME_SUNCG6_FBC_RASTEROP_ROP_11_1(x)    ((x) << 14)
                    153: #define TME_SUNCG6_FBC_RASTEROP_ROP_11_0(x)    ((x) << 12)
                    154: #define TME_SUNCG6_FBC_RASTEROP_ROP_10_1(x)    ((x) << 10)
                    155: #define TME_SUNCG6_FBC_RASTEROP_ROP_10_0(x)    ((x) <<  8)
                    156: #define TME_SUNCG6_FBC_RASTEROP_ROP_01_1(x)    ((x) <<  6)
                    157: #define TME_SUNCG6_FBC_RASTEROP_ROP_01_0(x)    ((x) <<  4)
                    158: #define TME_SUNCG6_FBC_RASTEROP_ROP_00_1(x)    ((x) <<  2)
                    159: #define TME_SUNCG6_FBC_RASTEROP_ROP_00_0(x)    ((x) <<  0)
                    160: #define  TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR      (0x0)
                    161: #define  TME_SUNCG6_FBC_RASTEROP_ROP_INVERT     (0x1)
                    162: #define  TME_SUNCG6_FBC_RASTEROP_ROP_NOP        (0x2)
                    163: #define  TME_SUNCG6_FBC_RASTEROP_ROP_SET        (0x3)
                    164: 
                    165: /* common FBC rasterop functions: */
                    166: 
                    167: /* copy: */
                    168: #define TME_SUNCG6_FBC_RASTEROP_FUNC_COPY                                      \
                    169:   (TME_SUNCG6_FBC_RASTEROP_PLANE_ONES                                          \
                    170:    | TME_SUNCG6_FBC_RASTEROP_PIXEL_ONES                                                \
                    171:    | TME_SUNCG6_FBC_RASTEROP_PATTERN_ONES                                      \
                    172:    | TME_SUNCG6_FBC_RASTEROP_POLYG_OVERLAP                                     \
                    173:    | TME_SUNCG6_FBC_RASTEROP_ATTR_SUPP                                         \
                    174:    | TME_SUNCG6_FBC_RASTEROP_ROP_11_1(TME_SUNCG6_FBC_RASTEROP_ROP_SET)         \
                    175:    | TME_SUNCG6_FBC_RASTEROP_ROP_11_0(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR)       \
                    176:    | TME_SUNCG6_FBC_RASTEROP_ROP_10_1(TME_SUNCG6_FBC_RASTEROP_ROP_SET)         \
                    177:    | TME_SUNCG6_FBC_RASTEROP_ROP_10_0(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR)       \
                    178:    | TME_SUNCG6_FBC_RASTEROP_ROP_01_1(TME_SUNCG6_FBC_RASTEROP_ROP_SET)         \
                    179:    | TME_SUNCG6_FBC_RASTEROP_ROP_01_0(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR)       \
                    180:    | TME_SUNCG6_FBC_RASTEROP_ROP_00_1(TME_SUNCG6_FBC_RASTEROP_ROP_SET)         \
                    181:    | TME_SUNCG6_FBC_RASTEROP_ROP_00_0(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR))
                    182: 
                    183: /* fill: */
                    184: #define TME_SUNCG6_FBC_RASTEROP_FUNC_FILL                                      \
                    185:   (TME_SUNCG6_FBC_RASTEROP_PLANE_ONES                                          \
                    186:    | TME_SUNCG6_FBC_RASTEROP_PIXEL_ONES                                                \
                    187:    | TME_SUNCG6_FBC_RASTEROP_PATTERN_ONES                                      \
                    188:    | TME_SUNCG6_FBC_RASTEROP_POLYG_OVERLAP                                     \
                    189:    | TME_SUNCG6_FBC_RASTEROP_ATTR_SUPP                                         \
                    190:    | TME_SUNCG6_FBC_RASTEROP_ROP_11_1(TME_SUNCG6_FBC_RASTEROP_ROP_SET)         \
                    191:    | TME_SUNCG6_FBC_RASTEROP_ROP_11_0(TME_SUNCG6_FBC_RASTEROP_ROP_SET)         \
                    192:    | TME_SUNCG6_FBC_RASTEROP_ROP_10_1(TME_SUNCG6_FBC_RASTEROP_ROP_SET)         \
                    193:    | TME_SUNCG6_FBC_RASTEROP_ROP_10_0(TME_SUNCG6_FBC_RASTEROP_ROP_SET)         \
                    194:    | TME_SUNCG6_FBC_RASTEROP_ROP_01_1(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR)       \
                    195:    | TME_SUNCG6_FBC_RASTEROP_ROP_01_0(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR)       \
                    196:    | TME_SUNCG6_FBC_RASTEROP_ROP_00_1(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR)       \
                    197:    | TME_SUNCG6_FBC_RASTEROP_ROP_00_0(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR))
                    198: 
                    199: /* flip: */
                    200: #define TME_SUNCG6_FBC_RASTEROP_FUNC_FLIP                                      \
                    201:   (TME_SUNCG6_FBC_RASTEROP_PLANE_ONES                                          \
                    202:    | TME_SUNCG6_FBC_RASTEROP_PIXEL_ONES                                                \
                    203:    | TME_SUNCG6_FBC_RASTEROP_PATTERN_ONES                                      \
                    204:    | TME_SUNCG6_FBC_RASTEROP_POLYG_OVERLAP                                     \
                    205:    | TME_SUNCG6_FBC_RASTEROP_ATTR_SUPP                                         \
                    206:    | TME_SUNCG6_FBC_RASTEROP_ROP_11_1(TME_SUNCG6_FBC_RASTEROP_ROP_INVERT)      \
                    207:    | TME_SUNCG6_FBC_RASTEROP_ROP_11_0(TME_SUNCG6_FBC_RASTEROP_ROP_INVERT)      \
                    208:    | TME_SUNCG6_FBC_RASTEROP_ROP_10_1(TME_SUNCG6_FBC_RASTEROP_ROP_INVERT)      \
                    209:    | TME_SUNCG6_FBC_RASTEROP_ROP_10_0(TME_SUNCG6_FBC_RASTEROP_ROP_INVERT)      \
                    210:    | TME_SUNCG6_FBC_RASTEROP_ROP_01_1(TME_SUNCG6_FBC_RASTEROP_ROP_INVERT)      \
                    211:    | TME_SUNCG6_FBC_RASTEROP_ROP_01_0(TME_SUNCG6_FBC_RASTEROP_ROP_INVERT)      \
                    212:    | TME_SUNCG6_FBC_RASTEROP_ROP_00_1(TME_SUNCG6_FBC_RASTEROP_ROP_INVERT)      \
                    213:    | TME_SUNCG6_FBC_RASTEROP_ROP_00_0(TME_SUNCG6_FBC_RASTEROP_ROP_INVERT))
                    214: 
                    215: /* NB: I couldn't reason out how the rop?? values work.  the values
                    216:    used by X11 and the NetBSD cgsix driver make some sense, but the
                    217:    0x6c60 used by the SUNW,501-2325 PROM for all of its blits and
                    218:    draws is confusing: */
                    219: #define TME_SUNCG6_FBC_RASTEROP_FUNC_PROM                                      \
                    220:   (TME_SUNCG6_FBC_RASTEROP_PLANE_ONES                                          \
                    221:    | TME_SUNCG6_FBC_RASTEROP_PIXEL_ONES                                                \
                    222:    | TME_SUNCG6_FBC_RASTEROP_PATTERN_ONES                                      \
                    223:    | TME_SUNCG6_FBC_RASTEROP_POLYG_OVERLAP                                     \
                    224:    | TME_SUNCG6_FBC_RASTEROP_ATTR_SUPP                                         \
                    225:    | TME_SUNCG6_FBC_RASTEROP_ROP_11_1(TME_SUNCG6_FBC_RASTEROP_ROP_INVERT)      \
                    226:    | TME_SUNCG6_FBC_RASTEROP_ROP_11_0(TME_SUNCG6_FBC_RASTEROP_ROP_NOP)         \
                    227:    | TME_SUNCG6_FBC_RASTEROP_ROP_10_1(TME_SUNCG6_FBC_RASTEROP_ROP_SET)         \
                    228:    | TME_SUNCG6_FBC_RASTEROP_ROP_10_0(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR)       \
                    229:    | TME_SUNCG6_FBC_RASTEROP_ROP_01_1(TME_SUNCG6_FBC_RASTEROP_ROP_INVERT)      \
                    230:    | TME_SUNCG6_FBC_RASTEROP_ROP_01_0(TME_SUNCG6_FBC_RASTEROP_ROP_NOP)         \
                    231:    | TME_SUNCG6_FBC_RASTEROP_ROP_00_1(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR)       \
                    232:    | TME_SUNCG6_FBC_RASTEROP_ROP_00_0(TME_SUNCG6_FBC_RASTEROP_ROP_CLEAR))
                    233: 
                    234: /* types: */
                    235: 
                    236: /* the cgsix pixel is eight bits: */
                    237: typedef tme_uint8_t tme_suncg6_pixel_t;
                    238: 
                    239: /* all cgsix registers are at least 32-bit aligned: */
                    240: typedef tme_uint32_t tme_suncg6_reg_t;
                    241: 
                    242: /* the card: */
                    243: struct tme_suncg6 {
                    244: 
                    245:   /* our generic Sun framebuffer: */
                    246:   struct tme_sunfb tme_suncg6_sunfb;
                    247: #define tme_suncg6_mutex tme_suncg6_sunfb.tme_sunfb_mutex
                    248: #define tme_suncg6_bus_subregion_memory tme_suncg6_sunfb.tme_sunfb_bus_subregion_memory
                    249: #define tme_suncg6_bus_subregion_regs tme_suncg6_sunfb.tme_sunfb_bus_subregion_regs
                    250: 
                    251:   /* the type of the cgsix: */
                    252:   tme_uint32_t tme_suncg6_type;
                    253: 
                    254:   /* the current framebuffer width and height: */
                    255:   tme_uint32_t tme_suncg6_width;
                    256:   tme_uint32_t tme_suncg6_height;
                    257: 
                    258:   /* the FHC: */
                    259: #define TME_SUNCG6_REG_FHC                     (0x300000)
                    260:   tme_suncg6_reg_t tme_suncg6_fhc;
                    261: 
                    262:   /* the THC: */
                    263: #define TME_SUNCG6_REG_THC_UNKNOWN_0x0         (0x301000)
                    264:   struct {
                    265: #define TME_SUNCG6_REG_THC_GROUP0              (0x301090)
                    266:     tme_suncg6_reg_t tme_suncg6_thc_unknown_0x90;
                    267:     tme_suncg6_reg_t tme_suncg6_thc_unknown_0x94;
                    268:   } tme_suncg6_thc_group0;
                    269:   struct {
                    270: #define TME_SUNCG6_REG_THC_GROUP1              (0x301800)
                    271:     tme_suncg6_reg_t tme_suncg6_thc_hsync1;
                    272:     tme_suncg6_reg_t tme_suncg6_thc_hsync2;
                    273:     tme_suncg6_reg_t tme_suncg6_thc_hsync3;
                    274:     tme_suncg6_reg_t tme_suncg6_thc_vsync1;
                    275:     tme_suncg6_reg_t tme_suncg6_thc_vsync2;
                    276:     tme_suncg6_reg_t tme_suncg6_thc_refresh;
                    277:     tme_suncg6_reg_t tme_suncg6_thc_misc;
                    278:     tme_suncg6_reg_t tme_suncg6_thc_unknown_0x81c[56];
                    279:     tme_suncg6_reg_t tme_suncg6_thc_cursor_xy;
                    280:     tme_suncg6_reg_t tme_suncg6_thc_cursor_mask[32];
                    281:     tme_suncg6_reg_t tme_suncg6_thc_cursor_bits[32];
                    282:   } tme_suncg6_thc_group1;
                    283: 
                    284:   /* the FBC: */
                    285:   struct {
                    286: #define TME_SUNCG6_REG_FBC_GROUP0              (0x700000)
                    287:     tme_suncg6_reg_t tme_suncg6_fbc_unknown_0x0;
                    288:     tme_suncg6_reg_t tme_suncg6_fbc_misc;
                    289:     tme_suncg6_reg_t tme_suncg6_fbc_clip_check;
                    290:     tme_suncg6_reg_t tme_suncg6_fbc_unknown_0xc;
                    291:     tme_suncg6_reg_t tme_suncg6_fbc_status;
                    292:     tme_suncg6_reg_t tme_suncg6_fbc_status_draw;
                    293:     tme_suncg6_reg_t tme_suncg6_fbc_status_blit;
                    294:     tme_suncg6_reg_t tme_suncg6_fbc_font;
                    295:     tme_suncg6_reg_t tme_suncg6_fbc_unknown_0x20[24];
                    296:     tme_suncg6_reg_t tme_suncg6_fbc_x0;
                    297:     tme_suncg6_reg_t tme_suncg6_fbc_y0;
                    298:     tme_suncg6_reg_t tme_suncg6_fbc_z0;
                    299:     tme_suncg6_reg_t tme_suncg6_fbc_color0;
                    300:     tme_suncg6_reg_t tme_suncg6_fbc_x1;
                    301:     tme_suncg6_reg_t tme_suncg6_fbc_y1;
                    302:     tme_suncg6_reg_t tme_suncg6_fbc_z1;
                    303:     tme_suncg6_reg_t tme_suncg6_fbc_color1;
                    304:     tme_suncg6_reg_t tme_suncg6_fbc_x2;
                    305:     tme_suncg6_reg_t tme_suncg6_fbc_y2;
                    306:     tme_suncg6_reg_t tme_suncg6_fbc_z2;
                    307:     tme_suncg6_reg_t tme_suncg6_fbc_color2;
                    308:     tme_suncg6_reg_t tme_suncg6_fbc_x3;
                    309:     tme_suncg6_reg_t tme_suncg6_fbc_y3;
                    310:     tme_suncg6_reg_t tme_suncg6_fbc_z3;
                    311:     tme_suncg6_reg_t tme_suncg6_fbc_color3;
                    312:     tme_suncg6_reg_t tme_suncg6_fbc_offx;
                    313:     tme_suncg6_reg_t tme_suncg6_fbc_offy;
                    314:     tme_suncg6_reg_t tme_suncg6_fbc_unknown_0xc8[2];
                    315:     tme_suncg6_reg_t tme_suncg6_fbc_inc_x;
                    316:     tme_suncg6_reg_t tme_suncg6_fbc_inc_y;
                    317:     tme_suncg6_reg_t tme_suncg6_fbc_unknown_0xd8[2];
                    318:     tme_suncg6_reg_t tme_suncg6_fbc_clip_min_x;
                    319:     tme_suncg6_reg_t tme_suncg6_fbc_clip_min_y;
                    320:     tme_suncg6_reg_t tme_suncg6_fbc_unknown_0xe8[2];
                    321:     tme_suncg6_reg_t tme_suncg6_fbc_clip_max_x;
                    322:     tme_suncg6_reg_t tme_suncg6_fbc_clip_max_y;
                    323:     tme_suncg6_reg_t tme_suncg6_fbc_unknown_0xf8[2];
                    324:     tme_suncg6_reg_t tme_suncg6_fbc_fg;
                    325:     tme_suncg6_reg_t tme_suncg6_fbc_bg;
                    326:     tme_suncg6_reg_t tme_suncg6_fbc_rasterop;
                    327:     tme_suncg6_reg_t tme_suncg6_fbc_pm;
                    328:     tme_suncg6_reg_t tme_suncg6_fbc_pixelm;
                    329:     tme_suncg6_reg_t tme_suncg6_fbc_unknown_0x114[2];
                    330:     tme_suncg6_reg_t tme_suncg6_fbc_patalign;
                    331:     tme_suncg6_reg_t tme_suncg6_fbc_pattern[8];
                    332:   } tme_suncg6_fbc_group0;
                    333:   struct {
                    334: #define TME_SUNCG6_REG_FBC_GROUP1              (0x700900)
                    335:     tme_suncg6_reg_t tme_suncg6_fbc_rect_abs_x;
                    336:     tme_suncg6_reg_t tme_suncg6_fbc_rect_abs_y;
                    337:   } tme_suncg6_fbc_group1;
                    338: 
                    339:   /* in the FBC, the rectangle absolute coordinate registers seem to
                    340:      be indexed: */
                    341: #define TME_SUNCG6_RECT_ABS_COUNT              (2)
                    342:   unsigned int tme_suncg6_fbc_rect_abs_x_i;
                    343:   unsigned int tme_suncg6_fbc_rect_abs_y_i;
                    344:   tme_suncg6_reg_t tme_suncg6_fbc_rect_abs_x[TME_SUNCG6_RECT_ABS_COUNT];
                    345:   tme_suncg6_reg_t tme_suncg6_fbc_rect_abs_y[TME_SUNCG6_RECT_ABS_COUNT];
                    346: 
                    347:   /* the TEC: */
                    348:   struct {
                    349: #define TME_SUNCG6_REG_TEC_GROUP0              (0x701000)
                    350:     tme_suncg6_reg_t tme_suncg6_tec_mv;
                    351:     tme_suncg6_reg_t tme_suncg6_tec_clip;
                    352:     tme_suncg6_reg_t tme_suncg6_tec_vdc;
                    353:   } tme_suncg6_tec_group0;
                    354: };
                    355: 
                    356: /* this does a blit: */
                    357: static void
                    358: _tme_suncg6_blit(struct tme_suncg6 *suncg6)
                    359: {
                    360:   tme_uint32_t fb_width;
                    361:   tme_uint32_t fb_height;
                    362:   tme_int32_t src_x;
                    363:   tme_int32_t src_y;
                    364:   tme_int32_t dst_x;
                    365:   tme_int32_t dst_y;
                    366:   tme_int32_t blit_width;
                    367:   tme_int32_t blit_height;
                    368:   int unsupported;
                    369:   tme_uint32_t offset_updated_first;
                    370:   tme_uint32_t offset_updated_last;
                    371:   const tme_suncg6_pixel_t *src;
                    372:   tme_suncg6_pixel_t *dst;
                    373: 
                    374:   /* get the framebuffer width and height: */
                    375:   fb_width = suncg6->tme_suncg6_width;
                    376:   fb_height = suncg6->tme_suncg6_height;
                    377: 
                    378:   /* get the blit source: */
                    379:   src_x = suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_x0;
                    380:   src_y = suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_y0;
                    381: 
                    382:   /* get the blit destination: */
                    383:   dst_x = suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_x2;
                    384:   dst_y = suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_y2;
                    385: 
                    386:   /* get the blit width and height: */
                    387:   blit_width = suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_x1;
                    388:   blit_width
                    389:     = (blit_width < src_x
                    390:        ? 0
                    391:        : (blit_width + 1 - src_x));
                    392:   blit_height = suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_y1;
                    393:   blit_height
                    394:     = (blit_height < src_y
                    395:        ? 0
                    396:        : (blit_height + 1 - src_y));
                    397: 
                    398:   /* check that this blit is supported: */
                    399:   unsupported = FALSE;
                    400:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_check != 0);
                    401:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_status != 0);
                    402:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_offx != 0);
                    403:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_offy != 0);
                    404:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_min_x != 0);
                    405:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_min_y != 0);
                    406:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_max_x != (fb_width - 1));
                    407:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_max_y != (fb_height - 1));
                    408:   unsupported
                    409:     |= (blit_width
                    410:        != (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_x3 < dst_x
                    411:            ? 0
                    412:            : (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_x3 + 1 - dst_x)));
                    413:   unsupported
                    414:     |= (blit_height
                    415:        != (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_y3 < dst_y
                    416:            ? 0
                    417:            : (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_y3 + 1 - dst_y)));
                    418:   if (__tme_predict_false(unsupported)) {
                    419:     tme_log(TME_SUNFB_LOG_HANDLE(&suncg6->tme_suncg6_sunfb), 0, EINVAL,
                    420:            (TME_SUNFB_LOG_HANDLE(&suncg6->tme_suncg6_sunfb),
                    421:             _("unsupported blit parameters")));
                    422:     return;
                    423:   }
                    424: 
                    425:   /* if any of the least coordinates aren't in the framebuffer: */
                    426:   if (src_x >= fb_width
                    427:       || dst_x >= fb_width
                    428:       || src_y >= fb_height
                    429:       || dst_y >= fb_height) {
                    430:     return;
                    431:   }
                    432: 
                    433:   /* make sure the blit height and width stay in the framebuffer: */
                    434:   blit_width = TME_MIN(blit_width,
                    435:                       TME_MIN(fb_width - src_x,
                    436:                               fb_width - dst_x));
                    437:   blit_height = TME_MIN(blit_height,
                    438:                        TME_MIN(fb_height - src_y,
                    439:                                fb_height - dst_y));
                    440: 
                    441:   /* if the blit height or width are zero: */
                    442:   if (blit_width == 0
                    443:       || blit_height == 0) {
                    444:     return;
                    445:   }
                    446: 
                    447:   /* get the offsets of the first and last bytes of the
                    448:      destination: */
                    449:   offset_updated_first = ((fb_width * dst_y) + dst_x);
                    450:   offset_updated_last
                    451:     = (offset_updated_first
                    452:        + (blit_width - 1)
                    453:        + (fb_width * (blit_height - 1)));
                    454: 
                    455:   /* get the first source and destination rows: */
                    456:   dst = (tme_suncg6_pixel_t *) suncg6->tme_suncg6_sunfb.tme_sunfb_memory;
                    457:   src = dst + ((fb_width * src_y) + src_x);
                    458:   dst += offset_updated_first;
                    459: 
                    460:   /* if this is a copy: */
                    461:   if (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_rasterop
                    462:       == TME_SUNCG6_FBC_RASTEROP_FUNC_COPY
                    463:       /* XXX FIXME - the rasterop function that the SUNW,501-2325 PROM
                    464:         uses for all of its blits and draws doesn't do a copy blit,
                    465:         but for now we treat it like it does: */
                    466:       || (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_rasterop
                    467:          == TME_SUNCG6_FBC_RASTEROP_FUNC_PROM)
                    468:       ) {
                    469: 
                    470:     /* if the copy is full-width: */
                    471:     if (blit_width == fb_width) {
                    472: 
                    473:       /* copy the source to the destination: */
                    474:       memmove(dst,
                    475:              src,
                    476:              sizeof(tme_suncg6_pixel_t) * blit_width * blit_height);
                    477:     }
                    478: 
                    479:     /* otherwise, the copy is not full-width: */
                    480:     else {
                    481: 
                    482:       /* copy the source to the destination: */
                    483:       do {
                    484:        memmove(dst,
                    485:                src,
                    486:                sizeof(tme_suncg6_pixel_t) * blit_width);
                    487:        dst += sizeof(tme_suncg6_pixel_t) * fb_width;
                    488:        src += sizeof(tme_suncg6_pixel_t) * fb_width;
                    489:       } while (--blit_height);
                    490:     }
                    491:   }
                    492: 
                    493:   /* otherwise, this is an unsupported blit: */
                    494:   else {
                    495:     tme_log(TME_SUNFB_LOG_HANDLE(&suncg6->tme_suncg6_sunfb), 0, EINVAL,
                    496:            (TME_SUNFB_LOG_HANDLE(&suncg6->tme_suncg6_sunfb),
                    497:             _("unsupported blit function")));
                    498:   }
                    499: 
                    500:   /* update the offsets of the first and last bytes updated in the
                    501:      real framebuffer memory: */
                    502:   offset_updated_first
                    503:     = TME_MIN(offset_updated_first,
                    504:              suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_first);
                    505:   offset_updated_last
                    506:     = TME_MAX(offset_updated_last,
                    507:              suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_last);
                    508:   suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_first = offset_updated_first;
                    509:   suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_last = offset_updated_last;
                    510: }
                    511: 
                    512: /* this does a draw: */
                    513: static void
                    514: _tme_suncg6_draw(struct tme_suncg6 *suncg6)
                    515: {
                    516:   tme_uint32_t fb_width;
                    517:   tme_uint32_t fb_height;
                    518:   unsigned int rect_abs_i;
                    519:   tme_int32_t draw_width;
                    520:   tme_int32_t dst_x;
                    521:   tme_int32_t draw_height;
                    522:   tme_int32_t dst_y;
                    523:   int unsupported;
                    524:   tme_uint32_t offset_updated_first;
                    525:   tme_uint32_t offset_updated_last;
                    526:   tme_suncg6_pixel_t *dst;
                    527:   tme_int32_t resid_width;
                    528: 
                    529:   /* get the framebuffer width and height: */
                    530:   fb_width = suncg6->tme_suncg6_width;
                    531:   fb_height = suncg6->tme_suncg6_height;
                    532: 
                    533:   /* get the draw width and destination x: */
                    534:   rect_abs_i = suncg6->tme_suncg6_fbc_rect_abs_x_i;
                    535:   draw_width = suncg6->tme_suncg6_fbc_rect_abs_x[rect_abs_i % TME_SUNCG6_RECT_ABS_COUNT];
                    536:   rect_abs_i = rect_abs_i - 1;
                    537:   dst_x = suncg6->tme_suncg6_fbc_rect_abs_x[rect_abs_i % TME_SUNCG6_RECT_ABS_COUNT];
                    538:   draw_width
                    539:     = (draw_width < dst_x
                    540:        ? 0
                    541:        : (draw_width + 1 - dst_x));
                    542: 
                    543:   /* get the draw height and destination y: */
                    544:   rect_abs_i = suncg6->tme_suncg6_fbc_rect_abs_y_i;
                    545:   draw_height = suncg6->tme_suncg6_fbc_rect_abs_y[rect_abs_i % TME_SUNCG6_RECT_ABS_COUNT];
                    546:   rect_abs_i = rect_abs_i - 1;
                    547:   dst_y = suncg6->tme_suncg6_fbc_rect_abs_y[rect_abs_i % TME_SUNCG6_RECT_ABS_COUNT];
                    548:   draw_height
                    549:     = (draw_height < dst_y
                    550:        ? 0
                    551:        : (draw_height + 1 - dst_y));
                    552: 
                    553:   /* check that this draw is supported: */
                    554:   unsupported = FALSE;
                    555:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_check != 0);
                    556:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_status != 0);
                    557:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_offx != 0);
                    558:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_offy != 0);
                    559:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_min_x != 0);
                    560:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_min_y != 0);
                    561:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_max_x != (fb_width - 1));
                    562:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_max_y != (fb_height - 1));
                    563:   if (__tme_predict_false(unsupported)) {
                    564:     tme_log(TME_SUNFB_LOG_HANDLE(&suncg6->tme_suncg6_sunfb), 0, EINVAL,
                    565:            (TME_SUNFB_LOG_HANDLE(&suncg6->tme_suncg6_sunfb),
                    566:             _("unsupported draw parameters")));
                    567:     return;
                    568:   }
                    569: 
                    570:   /* if the draw coordinate isn't in the framebuffer: */
                    571:   if (dst_x >= fb_width
                    572:       || dst_y >= fb_height) {
                    573:     return;
                    574:   }
                    575: 
                    576:   /* make sure the draw height and width stay in the framebuffer: */
                    577:   draw_width = TME_MIN(draw_width,
                    578:                       fb_width - dst_x);
                    579:   draw_height = TME_MIN(draw_height,
                    580:                        fb_height - dst_y);
                    581: 
                    582:   /* if the draw height or width are zero: */
                    583:   if (draw_width == 0
                    584:       || draw_height == 0) {
                    585:     return;
                    586:   }
                    587: 
                    588:   /* get the offsets of the first and last bytes of the
                    589:      destination: */
                    590:   offset_updated_first = ((fb_width * dst_y) + dst_x);
                    591:   offset_updated_last
                    592:     = (offset_updated_first
                    593:        + (draw_width - 1)
                    594:        + (fb_width * (draw_height - 1)));
                    595: 
                    596:   /* get the first destination row: */
                    597:   dst = (tme_suncg6_pixel_t *) suncg6->tme_suncg6_sunfb.tme_sunfb_memory;
                    598:   dst += offset_updated_first;
                    599: 
                    600:   /* if this is a fill: */
                    601:   if (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_rasterop
                    602:       == TME_SUNCG6_FBC_RASTEROP_FUNC_FILL
                    603:       /* XXX FIXME - the rasterop function that the SUNW,501-2325 PROM
                    604:         uses for all of its blits and draws doesn't do a fill draw,
                    605:         but for now we treat it like it does: */
                    606:       || (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_rasterop
                    607:          == TME_SUNCG6_FBC_RASTEROP_FUNC_PROM)
                    608:       ) {
                    609: 
                    610:     /* if the fill is full-width: */
                    611:     if (draw_width == fb_width) {
                    612: 
                    613:       /* fill the destination: */
                    614:       memset(dst,
                    615:             (tme_uint8_t) suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_fg,
                    616:             sizeof(tme_suncg6_pixel_t) * draw_width * draw_height);
                    617:     }
                    618: 
                    619:     /* otherwise, the fill is not full-width: */
                    620:     else {
                    621: 
                    622:       /* fill the destination: */
                    623:       do {
                    624:        memset(dst,
                    625:               (tme_uint8_t) suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_fg,
                    626:               sizeof(tme_suncg6_pixel_t) * draw_width);
                    627:        dst += sizeof(tme_suncg6_pixel_t) * fb_width;
                    628:       } while (--draw_height);
                    629:     }
                    630:   }
                    631: 
                    632:   /* otherwise, if this is an invert: */
                    633:   else if (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_rasterop
                    634:           == TME_SUNCG6_FBC_RASTEROP_FUNC_FLIP) {
                    635: 
                    636:     /* do the inversion: */
                    637:     /* XXX FIXME - the inversion almost certainly isn't this
                    638:        simple: */
                    639:     do {
                    640:       resid_width = draw_width;
                    641:       do {
                    642:        *(dst++) ^= 0xff;
                    643:       } while (--resid_width);
                    644:       dst = (dst - draw_width) + fb_width;
                    645:     } while (--draw_height);
                    646:   }
                    647: 
                    648:   /* otherwise, this is an unsupported draw: */
                    649:   else {
                    650:     tme_log(TME_SUNFB_LOG_HANDLE(&suncg6->tme_suncg6_sunfb), 0, EINVAL,
                    651:            (TME_SUNFB_LOG_HANDLE(&suncg6->tme_suncg6_sunfb),
                    652:             _("unsupported draw function")));
                    653:   }
                    654: 
                    655:   /* update the offsets of the first and last bytes updated in the
                    656:      real framebuffer memory: */
                    657:   offset_updated_first
                    658:     = TME_MIN(offset_updated_first,
                    659:              suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_first);
                    660:   offset_updated_last
                    661:     = TME_MAX(offset_updated_last,
                    662:              suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_last);
                    663:   suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_first = offset_updated_first;
                    664:   suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_last = offset_updated_last;
                    665: }
                    666: 
                    667: /* this does a font draw: */
                    668: static void
                    669: _tme_suncg6_font(struct tme_suncg6 *suncg6,
                    670:                 tme_suncg6_reg_t font)
                    671: {
                    672:   tme_uint32_t fb_width;
                    673:   tme_uint32_t fb_height;
                    674:   tme_int32_t dst_x;
                    675:   tme_int32_t dst_y;
                    676:   tme_int32_t draw_width;
                    677:   int unsupported;
                    678:   tme_uint32_t offset_updated_first;
                    679:   tme_uint32_t offset_updated_last;
                    680:   tme_suncg6_pixel_t *dst;
                    681:   tme_uint16_t pixels;
                    682: 
                    683:   /* get the framebuffer width and height: */
                    684:   fb_width = suncg6->tme_suncg6_width;
                    685:   fb_height = suncg6->tme_suncg6_height;
                    686: 
                    687:   /* get the font draw destination: */
                    688:   dst_x = suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_x0;
                    689:   dst_y = suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_y0;
                    690: 
                    691:   /* get the font draw width: */
                    692:   draw_width = suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_x1;
                    693:   draw_width
                    694:     = (draw_width < dst_x
                    695:        ? 0
                    696:        : (draw_width + 1 - dst_x));
                    697:   
                    698:   /* check that this font draw is supported: */
                    699:   unsupported = FALSE;
                    700:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_check != 0);
                    701:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_status != 0);
                    702:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_offx != 0);
                    703:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_offy != 0);
                    704:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_min_x != 0);
                    705:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_min_y != 0);
                    706:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_max_x != (fb_width - 1));
                    707:   unsupported |= (suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_clip_max_y != (fb_height - 1));
                    708:   if (__tme_predict_false(unsupported)) {
                    709:     tme_log(TME_SUNFB_LOG_HANDLE(&suncg6->tme_suncg6_sunfb), 0, EINVAL,
                    710:            (TME_SUNFB_LOG_HANDLE(&suncg6->tme_suncg6_sunfb),
                    711:             _("unsupported font draw parameters")));
                    712:     return;
                    713:   }
                    714: 
                    715:   /* if the font draw coordinate isn't in the framebuffer: */
                    716:   if (dst_x >= fb_width
                    717:       || dst_y >= fb_height) {
                    718:     return;
                    719:   }
                    720: 
                    721:   /* make sure the font draw width stays in the framebuffer: */
                    722:   draw_width = TME_MIN(draw_width,
                    723:                       fb_width - dst_x);
                    724: 
                    725:   /* if the draw width is zero: */
                    726:   if (draw_width == 0) {
                    727:     return;
                    728:   }
                    729: 
                    730:   /* get the offsets of the first and last bytes of the
                    731:      destination: */
                    732:   offset_updated_first = ((fb_width * dst_y) + dst_x);
                    733:   offset_updated_last
                    734:     = (offset_updated_first
                    735:        + (draw_width - 1));
                    736: 
                    737:   /* get the first destination row: */
                    738:   dst = (tme_suncg6_pixel_t *) suncg6->tme_suncg6_sunfb.tme_sunfb_memory;
                    739:   dst += offset_updated_first;
                    740: 
                    741:   /* get the foreground and background pixels: */
                    742:   pixels = (tme_suncg6_pixel_t) suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_fg;
                    743:   pixels <<= (8 * sizeof(tme_suncg6_pixel_t));
                    744:   pixels += (tme_suncg6_pixel_t) suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_bg;
                    745: 
                    746:   /* do the font draw: */
                    747:   do {
                    748:     *(dst++)
                    749:       = ((tme_suncg6_pixel_t)
                    750:         (pixels
                    751:          >> ((0 - (((tme_int32_t) font) < 0))
                    752:              & (8 * sizeof(tme_suncg6_pixel_t)))));
                    753:     font <<= 1;
                    754:   } while (--draw_width);
                    755: 
                    756:   /* advance after the font draw: */
                    757:   suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_x0 += suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_inc_x;
                    758:   suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_x1 += suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_inc_x;
                    759:   suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_y0 += suncg6->tme_suncg6_fbc_group0.tme_suncg6_fbc_inc_y;
                    760: 
                    761:   /* update the offsets of the first and last bytes updated in the
                    762:      real framebuffer memory: */
                    763:   offset_updated_first
                    764:     = TME_MIN(offset_updated_first,
                    765:              suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_first);
                    766:   offset_updated_last
                    767:     = TME_MAX(offset_updated_last,
                    768:              suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_last);
                    769:   suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_first = offset_updated_first;
                    770:   suncg6->tme_suncg6_sunfb.tme_sunfb_offset_updated_last = offset_updated_last;
                    771: }
                    772: 
                    773: /* the ALT bus cycle handler: */
                    774: static void
                    775: _tme_suncg6_bus_cycle_alt(struct tme_sunfb *sunfb,
                    776:                          struct tme_bus_cycle *master_cycle,
                    777:                          tme_uint32_t *_master_fast_cycle_types,
                    778:                          struct tme_completion *master_completion)
                    779: {
                    780:   struct tme_suncg6 *suncg6;
                    781:   tme_bus_addr32_t reg;
                    782:   tme_suncg6_reg_t *_reg;
                    783:   tme_suncg6_reg_t value32_buffer;
                    784:   tme_suncg6_reg_t value32;
                    785: 
                    786:   /* recover our data structure: */
                    787:   suncg6 = (struct tme_suncg6 *) sunfb;
                    788: 
                    789:   /* get the register: */
                    790:   reg = master_cycle->tme_bus_cycle_address;
                    791: 
                    792:   /* convert the register into a pointer: */
                    793:   _reg = NULL;
                    794: 
                    795:   /* if this is a write: */
                    796:   if (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) {
                    797: 
                    798:     /* run the bus cycle: */
                    799:     tme_bus_cycle_xfer_reg(master_cycle, 
                    800:                           &value32_buffer,
                    801:                           TME_BUS32_LOG2);
                    802:     value32 = value32_buffer;
                    803:   }
                    804: 
                    805:   /* otherwise, this must be a read: */
                    806:   else {
                    807:     assert (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_READ);
                    808: 
                    809:     /* this must be a maintained register: */
                    810:     if (_reg == NULL) {
                    811:       abort();
                    812:     }
                    813:     value32 = *_reg;
                    814: 
                    815:     /* run the bus cycle: */
                    816:     value32_buffer = value32;
                    817:     tme_bus_cycle_xfer_reg(master_cycle, 
                    818:                           &value32_buffer,
                    819:                           TME_BUS32_LOG2);
                    820:   }
                    821: 
                    822:   /* complete the cycle: */
                    823:   master_completion->tme_completion_error = TME_OK;
                    824:   tme_memory_barrier(master_completion, sizeof(*master_completion), TME_MEMORY_BARRIER_WRITE_BEFORE_WRITE);
                    825:   tme_completion_validate(master_completion);
                    826:   *_master_fast_cycle_types = 0;
                    827: 
                    828:   tme_log(TME_SUNFB_LOG_HANDLE(sunfb), 2000, TME_OK,
                    829:          (TME_SUNFB_LOG_HANDLE(sunfb),
                    830:           _("ALT 0x%06" TME_PRIx32 " %s%s 0x%08" TME_PRIx32),
                    831:           reg,
                    832:           (_reg == NULL
                    833:            ? "UNKNOWN "
                    834:            : ""),
                    835:           (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE
                    836:            ? "<-"
                    837:            : "->"),
                    838:           value32));
                    839: }
                    840: 
                    841: /* the FHC and THC bus cycle handler: */
                    842: static void
                    843: _tme_suncg6_bus_cycle_fhc_thc(struct tme_sunfb *sunfb,
                    844:                              struct tme_bus_cycle *master_cycle,
                    845:                              tme_uint32_t *_master_fast_cycle_types,
                    846:                              struct tme_completion *master_completion)
                    847: {
                    848:   struct tme_suncg6 *suncg6;
                    849:   tme_bus_addr32_t reg;
                    850:   tme_suncg6_reg_t *_reg;
                    851:   tme_suncg6_reg_t value32_buffer;
                    852:   tme_suncg6_reg_t value32;
                    853:   tme_suncg6_reg_t reg_mask_ro;
                    854: 
                    855:   /* recover our data structure: */
                    856:   suncg6 = (struct tme_suncg6 *) sunfb;
                    857: 
                    858:   /* get the register: */
                    859:   reg = master_cycle->tme_bus_cycle_address;
                    860: 
                    861:   /* convert the register into a pointer: */
                    862:   if (reg >= TME_SUNCG6_REG_THC_UNKNOWN_0x0) {
                    863:     _reg = (TME_SUNCG6_REG_POINTER(suncg6, reg,THC,thc,0)
                    864:            : TME_SUNCG6_REG_POINTER(suncg6, reg,THC,thc,1)
                    865:            : NULL);
                    866:   }
                    867:   else {
                    868:     reg = TME_SUNCG6_REG_FHC;
                    869:     _reg = &suncg6->tme_suncg6_fhc;
                    870:   }
                    871: 
                    872:   /* if this is a write: */
                    873:   if (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) {
                    874: 
                    875:     /* run the bus cycle: */
                    876:     tme_bus_cycle_xfer_reg(master_cycle, 
                    877:                           &value32_buffer,
                    878:                           TME_BUS32_LOG2);
                    879:     value32 = value32_buffer;
                    880: 
                    881:     /* assume that none of the register is read-only: */
                    882:     reg_mask_ro = 0;
                    883: 
                    884:     /* dispatch on the register: */
                    885:     switch (reg) {
                    886: 
                    887:       /* the FHC: */
                    888:     case TME_SUNCG6_REG_FHC:
                    889:       reg_mask_ro
                    890:        = (TME_SUNCG6_FHC_ID_MASK
                    891:           + TME_SUNCG6_FHC_REVISION_MASK
                    892:           + TME_SUNCG6_FHC_SIZE_MASK);
                    893:       break;
                    894: 
                    895:       /* the THC miscellaneous register: */
                    896:     case TME_SUNCG6_REG_THC(1,misc):
                    897:       reg_mask_ro
                    898:        = (TME_SUNCG6_THC_MISC_REVISION_MASK
                    899:           );
                    900:       break;
                    901: 
                    902:     default:
                    903:       break;
                    904:     }
                    905: 
                    906:     /* if this is a maintained register: */
                    907:     if (_reg != NULL) {
                    908:       *_reg
                    909:        = ((*_reg
                    910:            & reg_mask_ro)
                    911:           + (value32
                    912:              & ~reg_mask_ro));
                    913:     }
                    914:   }
                    915: 
                    916:   /* otherwise, this is a read: */
                    917:   else {
                    918:     assert (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_READ);
                    919: 
                    920:     /* dispatch on the register: */
                    921:     switch (reg) {
                    922: 
                    923:     default:
                    924:       break;
                    925:     }
                    926: 
                    927:     /* this must be a maintained register: */
                    928:     if (_reg == NULL) {
                    929:       abort();
                    930:     }
                    931:     value32 = *_reg;
                    932: 
                    933:     /* run the bus cycle: */
                    934:     value32_buffer = value32;
                    935:     tme_bus_cycle_xfer_reg(master_cycle, 
                    936:                           &value32_buffer,
                    937:                           TME_BUS32_LOG2);
                    938:   }
                    939: 
                    940:   /* complete the cycle: */
                    941:   master_completion->tme_completion_error = TME_OK;
                    942:   tme_memory_barrier(master_completion, sizeof(*master_completion), TME_MEMORY_BARRIER_WRITE_BEFORE_WRITE);
                    943:   tme_completion_validate(master_completion);
                    944:   *_master_fast_cycle_types = 0;
                    945: 
                    946:   tme_log(TME_SUNFB_LOG_HANDLE(sunfb), 2000, TME_OK,
                    947:          (TME_SUNFB_LOG_HANDLE(sunfb),
                    948:           _("%s 0x%06" TME_PRIx32 " %s%s 0x%08" TME_PRIx32),
                    949:           (reg >= TME_SUNCG6_REG_THC_UNKNOWN_0x0
                    950:            ? "THC"
                    951:            : "FHC"),
                    952:           reg,
                    953:           (_reg == NULL
                    954:            ? "UNKNOWN "
                    955:            : ""),
                    956:           (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE
                    957:            ? "<-"
                    958:            : "->"),
                    959:           value32));
                    960: }
                    961: 
                    962: /* the FBC bus cycle handler: */
                    963: static void
                    964: _tme_suncg6_bus_cycle_fbc(struct tme_sunfb *sunfb,
                    965:                          struct tme_bus_cycle *master_cycle,
                    966:                          tme_uint32_t *_master_fast_cycle_types,
                    967:                          struct tme_completion *master_completion)
                    968: {
                    969:   struct tme_suncg6 *suncg6;
                    970:   tme_bus_addr32_t reg;
                    971:   tme_suncg6_reg_t *_reg;
                    972:   tme_suncg6_reg_t value32_buffer;
                    973:   tme_suncg6_reg_t value32;
                    974:   tme_suncg6_reg_t reg_mask_ro;
                    975: 
                    976:   /* recover our data structure: */
                    977:   suncg6 = (struct tme_suncg6 *) sunfb;
                    978: 
                    979:   /* get the register: */
                    980:   reg = master_cycle->tme_bus_cycle_address;
                    981: 
                    982:   /* convert the register into a pointer: */
                    983:   _reg
                    984:     = (TME_SUNCG6_REG_POINTER(suncg6, reg,FBC,fbc,0)
                    985:        : TME_SUNCG6_REG_POINTER(suncg6, reg,FBC,fbc,1)
                    986:        : NULL);
                    987: 
                    988:   /* if this is a write: */
                    989:   if (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) {
                    990: 
                    991:     /* run the bus cycle: */
                    992:     tme_bus_cycle_xfer_reg(master_cycle, 
                    993:                           &value32_buffer,
                    994:                           TME_BUS32_LOG2);
                    995:     value32 = value32_buffer;
                    996: 
                    997:     /* assume that none of the register is read-only: */
                    998:     reg_mask_ro = 0;
                    999: 
                   1000:     /* dispatch on the register: */
                   1001:     switch (reg) {
                   1002: 
                   1003:       /* a write of the font register: */
                   1004:     case TME_SUNCG6_REG_FBC(0,font):
                   1005:       _tme_suncg6_font(suncg6, value32);
                   1006:       break;
                   1007: 
                   1008:       /* a write of the rectangle absolute coordinate registers: */
                   1009:     case TME_SUNCG6_REG_FBC(1,rect_abs_x):
                   1010:       suncg6->tme_suncg6_fbc_rect_abs_x_i
                   1011:        = ((suncg6->tme_suncg6_fbc_rect_abs_x_i + 1)
                   1012:           % TME_SUNCG6_RECT_ABS_COUNT);
                   1013:       _reg = &suncg6->tme_suncg6_fbc_rect_abs_x[suncg6->tme_suncg6_fbc_rect_abs_x_i];
                   1014:       break;
                   1015:     case TME_SUNCG6_REG_FBC(1,rect_abs_y):
                   1016:       suncg6->tme_suncg6_fbc_rect_abs_y_i
                   1017:        = ((suncg6->tme_suncg6_fbc_rect_abs_y_i + 1)
                   1018:           % TME_SUNCG6_RECT_ABS_COUNT);
                   1019:       _reg = &suncg6->tme_suncg6_fbc_rect_abs_y[suncg6->tme_suncg6_fbc_rect_abs_y_i];
                   1020:       break;
                   1021: 
                   1022:     default:
                   1023:       break;
                   1024:     }
                   1025: 
                   1026:     /* if this is a maintained register: */
                   1027:     if (_reg != NULL) {
                   1028:       *_reg
                   1029:        = ((*_reg
                   1030:            & reg_mask_ro)
                   1031:           + (value32
                   1032:              & ~reg_mask_ro));
                   1033:     }
                   1034:   }
                   1035: 
                   1036:   /* otherwise, this is a read: */
                   1037:   else {
                   1038:     assert (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_READ);
                   1039: 
                   1040:     /* dispatch on the register: */
                   1041:     switch (reg) {
                   1042: 
                   1043:       /* a read of the status register: */
                   1044:     case TME_SUNCG6_REG_FBC(0,status):
                   1045:       *_reg = 0;
                   1046:       break;
                   1047: 
                   1048:       /* a read of the blit status register: */
                   1049:     case TME_SUNCG6_REG_FBC(0,status_blit):
                   1050: 
                   1051:       /* trigger a blit: */
                   1052:       _tme_suncg6_blit(suncg6);
                   1053: 
                   1054:       *_reg = 0;
                   1055:       break;
                   1056: 
                   1057:       /* a read of the drawing status register: */
                   1058:     case TME_SUNCG6_REG_FBC(0,status_draw):
                   1059: 
                   1060:       /* trigger a draw: */
                   1061:       _tme_suncg6_draw(suncg6);
                   1062: 
                   1063:       *_reg = 0;
                   1064:       break;
                   1065: 
                   1066:     default:
                   1067:       break;
                   1068:     }
                   1069: 
                   1070:     /* this must be a maintained register: */
                   1071:     if (_reg == NULL) {
                   1072:       abort();
                   1073:     }
                   1074:     value32 = *_reg;
                   1075: 
                   1076:     /* run the bus cycle: */
                   1077:     value32_buffer = value32;
                   1078:     tme_bus_cycle_xfer_reg(master_cycle, 
                   1079:                           &value32_buffer,
                   1080:                           TME_BUS32_LOG2);
                   1081:   }
                   1082: 
                   1083:   /* complete the cycle: */
                   1084:   master_completion->tme_completion_error = TME_OK;
                   1085:   tme_memory_barrier(master_completion, sizeof(*master_completion), TME_MEMORY_BARRIER_WRITE_BEFORE_WRITE);
                   1086:   tme_completion_validate(master_completion);
                   1087:   *_master_fast_cycle_types = 0;
                   1088: 
                   1089:   tme_log(TME_SUNFB_LOG_HANDLE(sunfb), 2000, TME_OK,
                   1090:          (TME_SUNFB_LOG_HANDLE(sunfb),
                   1091:           _("FBC 0x%06" TME_PRIx32 " %s%s 0x%08" TME_PRIx32),
                   1092:           reg,
                   1093:           (_reg == NULL
                   1094:            ? "UNKNOWN "
                   1095:            : ""),
                   1096:           (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE
                   1097:            ? "<-"
                   1098:            : "->"),
                   1099:           value32));
                   1100: }
                   1101: 
                   1102: /* the TEC bus cycle handler: */
                   1103: static void
                   1104: _tme_suncg6_bus_cycle_tec(struct tme_sunfb *sunfb,
                   1105:                          struct tme_bus_cycle *master_cycle,
                   1106:                          tme_uint32_t *_master_fast_cycle_types,
                   1107:                          struct tme_completion *master_completion)
                   1108: {
                   1109:   struct tme_suncg6 *suncg6;
                   1110:   tme_bus_addr32_t reg;
                   1111:   tme_suncg6_reg_t *_reg;
                   1112:   tme_suncg6_reg_t value32_buffer;
                   1113:   tme_suncg6_reg_t value32;
                   1114:   tme_suncg6_reg_t reg_mask_ro;
                   1115: 
                   1116:   /* recover our data structure: */
                   1117:   suncg6 = (struct tme_suncg6 *) sunfb;
                   1118: 
                   1119:   /* get the register: */
                   1120:   reg = master_cycle->tme_bus_cycle_address;
                   1121: 
                   1122:   /* convert the register into a pointer: */
                   1123:   _reg
                   1124:     = (TME_SUNCG6_REG_POINTER(suncg6, reg,TEC,tec,0)
                   1125:        : NULL);
                   1126: 
                   1127:   /* if this is a write: */
                   1128:   if (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) {
                   1129: 
                   1130:     /* run the bus cycle: */
                   1131:     tme_bus_cycle_xfer_reg(master_cycle, 
                   1132:                           &value32_buffer,
                   1133:                           TME_BUS32_LOG2);
                   1134:     value32 = value32_buffer;
                   1135: 
                   1136:     /* assume that none of the register is read-only: */
                   1137:     reg_mask_ro = 0;
                   1138: 
                   1139:     /* dispatch on the register: */
                   1140:     switch (reg) {
                   1141: 
                   1142:     default:
                   1143:       break;
                   1144:     }
                   1145: 
                   1146:     /* if this is a maintained register: */
                   1147:     if (_reg != NULL) {
                   1148:       *_reg
                   1149:        = ((*_reg
                   1150:            & reg_mask_ro)
                   1151:           + (value32
                   1152:              & ~reg_mask_ro));
                   1153:     }
                   1154:   }
                   1155: 
                   1156:   /* otherwise, this is a read: */
                   1157:   else {
                   1158:     assert (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_READ);
                   1159: 
                   1160:     /* dispatch on the register: */
                   1161:     switch (reg) {
                   1162: 
                   1163:     default:
                   1164:       break;
                   1165:     }
                   1166: 
                   1167:     /* this must be a maintained register: */
                   1168:     if (_reg == NULL) {
                   1169:       abort();
                   1170:     }
                   1171:     value32 = *_reg;
                   1172: 
                   1173:     /* run the bus cycle: */
                   1174:     value32_buffer = value32;
                   1175:     tme_bus_cycle_xfer_reg(master_cycle, 
                   1176:                           &value32_buffer,
                   1177:                           TME_BUS32_LOG2);
                   1178:   }
                   1179: 
                   1180:   /* complete the cycle: */
                   1181:   master_completion->tme_completion_error = TME_OK;
                   1182:   tme_memory_barrier(master_completion, sizeof(*master_completion), TME_MEMORY_BARRIER_WRITE_BEFORE_WRITE);
                   1183:   tme_completion_validate(master_completion);
                   1184:   *_master_fast_cycle_types = 0;
                   1185: 
                   1186:   tme_log(TME_SUNFB_LOG_HANDLE(sunfb), 2000, TME_OK,
                   1187:          (TME_SUNFB_LOG_HANDLE(sunfb),
                   1188:           _("TEC 0x%06" TME_PRIx32 " %s%s 0x%08" TME_PRIx32),
                   1189:           reg,
                   1190:           (_reg == NULL
                   1191:            ? "UNKNOWN "
                   1192:            : ""),
                   1193:           (master_cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE
                   1194:            ? "<-"
                   1195:            : "->"),
                   1196:           value32));
                   1197: }
                   1198: 
                   1199: #if TME_SUNFB_BUS_TRANSITION
                   1200: 
                   1201: /* this is the bus cycle transition glue: */
                   1202: #define _tme_suncg6_bus_cycle_transition(regs)                                         \
                   1203: static int                                                                             \
                   1204: _TME_CONCAT(_tme_suncg6_bus_cycle_transition_,regs)(void *_sunfb,                      \
                   1205:                                                    struct tme_bus_cycle *master_cycle) \
                   1206: {                                                                                      \
                   1207:   return (tme_sunfb_bus_cycle_transition(_sunfb,                                       \
                   1208:                                         master_cycle,                                  \
                   1209:                                         _TME_CONCAT(_tme_suncg6_bus_cycle_,regs)));    \
                   1210: }                                                                                      \
                   1211: struct _tme_suncg6_bus_cycle_transition
                   1212: _tme_suncg6_bus_cycle_transition(alt);
                   1213: _tme_suncg6_bus_cycle_transition(fhc_thc);
                   1214: _tme_suncg6_bus_cycle_transition(fbc);
                   1215: _tme_suncg6_bus_cycle_transition(tec);
                   1216: #define _tme_suncg6_bus_cycle_alt _tme_suncg6_bus_cycle_transition_alt
                   1217: #define _tme_suncg6_bus_cycle_fhc_thc _tme_suncg6_bus_cycle_transition_fhc_thc
                   1218: #define _tme_suncg6_bus_cycle_fbc _tme_suncg6_bus_cycle_transition_fbc
                   1219: #define _tme_suncg6_bus_cycle_tec _tme_suncg6_bus_cycle_transition_tec
                   1220: #undef _tme_suncg6_bus_cycle_transition
                   1221: 
                   1222: #endif /* TME_SUNFB_BUS_TRANSITION */
                   1223: 
                   1224: /* this sets the cgsix type: */
                   1225: static const char *
                   1226: _tme_suncg6_type_set(struct tme_sunfb *sunfb, const char *cg6_type_string)
                   1227: {
                   1228:   struct tme_suncg6 *suncg6;
                   1229:   tme_uint32_t cg6_type;
                   1230:   tme_suncg6_reg_t fhc;
                   1231:   tme_suncg6_reg_t thc_misc;
                   1232: 
                   1233:   /* recover our data structure: */
                   1234:   suncg6 = (struct tme_suncg6 *) sunfb;
                   1235: 
                   1236:   /* see if this is a good type: */
                   1237:   cg6_type = TME_SUNCG6_TYPE_NULL;
                   1238:   if (TME_ARG_IS(cg6_type_string, "501-2325")) {
                   1239:     cg6_type = TME_SUNCG6_TYPE_501_2325;
                   1240:   }
                   1241: 
                   1242:   /* set the new type: */
                   1243:   suncg6->tme_suncg6_type = cg6_type;
                   1244: 
                   1245:   /* zero various registers: */
                   1246:   fhc = 0;
                   1247:   thc_misc = 0;
                   1248: 
                   1249:   /* dispatch on the new type: */
                   1250:   switch (cg6_type) {
                   1251: 
                   1252:     /* if this was a bad type, return a string of types: */
                   1253:   default: assert(FALSE);
                   1254:   case TME_SUNCG6_TYPE_NULL:
                   1255:     return ("501-2325");
                   1256: 
                   1257:   case TME_SUNCG6_TYPE_501_2325:
                   1258:     TME_FIELD_MASK_DEPOSITU(fhc, TME_SUNCG6_FHC_ID_MASK, 0x63);
                   1259:     TME_FIELD_MASK_DEPOSITU(fhc, TME_SUNCG6_FHC_REVISION_MASK, 0xb);
                   1260:     TME_FIELD_MASK_DEPOSITU(thc_misc, TME_SUNCG6_THC_MISC_REVISION_MASK, 0x4);
                   1261:     sunfb->tme_sunfb_bus_signal_int = TME_BUS_SIGNAL_INT(5);
                   1262:     break;
                   1263:   }
                   1264: 
                   1265:   /* set various initial registers: */
                   1266:   suncg6->tme_suncg6_fhc = fhc;
                   1267:   suncg6->tme_suncg6_thc_group1.tme_suncg6_thc_misc = thc_misc;
                   1268: 
                   1269:   /* success: */
                   1270:   return (NULL);
                   1271: }
                   1272: 
                   1273: /* the new sun cgsix function: */
                   1274: int
                   1275: tme_sun_cgsix(struct tme_element *element, const char * const *args, char **_output)
                   1276: {
                   1277:   struct tme_suncg6 *suncg6;
                   1278:   struct tme_sunfb *sunfb;
                   1279:   tme_uint8_t *cmap;
                   1280:   int rc;
                   1281:   tme_suncg6_reg_t fhc;
                   1282: 
                   1283:   /* start the suncg6 structure: */
                   1284:   suncg6 = tme_new0(struct tme_suncg6, 1);
                   1285:   suncg6->tme_suncg6_sunfb.tme_sunfb_element = element;
                   1286: 
                   1287:   /* initialize the sunfb structure: */
                   1288:   sunfb = &suncg6->tme_suncg6_sunfb;
                   1289:   sunfb->tme_sunfb_class = TME_FB_XLAT_CLASS_COLOR;
                   1290:   sunfb->tme_sunfb_depth = 8;
                   1291:   sunfb->tme_sunfb_type_set = _tme_suncg6_type_set;
                   1292:   sunfb->tme_sunfb_flags
                   1293:     |= ((!TME_SUNFB_FLAG_BT458_CMAP_PACKED)
                   1294:        | TME_SUNFB_FLAG_BT458_BYTE_D24_D31);
                   1295: 
                   1296:   /* possible cgsix framebuffer sizes: */
                   1297:   suncg6->tme_suncg6_sunfb.tme_sunfb_size
                   1298:     = (TME_SUNFB_SIZE_1024_768
                   1299:        | TME_SUNFB_SIZE_1152_900
                   1300:        | TME_SUNFB_SIZE_1280_1024
                   1301:        | TME_SUNFB_SIZE_1600_1280);
                   1302: 
                   1303:   /* assume that this is not a P4 cgsix: */
                   1304:   suncg6->tme_suncg6_bus_subregion_p4.tme_bus_subregion_address_first = 1;
                   1305:   suncg6->tme_suncg6_bus_subregion_p4.tme_bus_subregion_address_last = 0;
                   1306:   suncg6->tme_suncg6_bus_handler_p4 = NULL;
                   1307: 
                   1308:   /* the DAC registers: */
                   1309:   suncg6->tme_suncg6_bus_subregion_dac.tme_bus_subregion_address_first = TME_SUNCG6_REG_DAC;
                   1310:   suncg6->tme_suncg6_bus_subregion_dac.tme_bus_subregion_address_last = TME_SUNCG6_REG_ALT - 1;
                   1311:   suncg6->tme_suncg6_bus_handler_dac = tme_sunfb_bus_cycle_bt458;
                   1312: 
                   1313:   /* the ALT registers: */
                   1314:   suncg6->tme_suncg6_bus_subregion_alt.tme_bus_subregion_address_first = TME_SUNCG6_REG_ALT;
                   1315:   suncg6->tme_suncg6_bus_subregion_alt.tme_bus_subregion_address_last = TME_SUNCG6_REG_ALT + TME_SUNCG6_SIZ_ALT - 1;
                   1316:   suncg6->tme_suncg6_bus_handler_alt = _tme_suncg6_bus_cycle_alt;
                   1317: 
                   1318:   /* the FHC and THC registers: */
                   1319:   suncg6->tme_suncg6_bus_subregion_fhc_thc.tme_bus_subregion_address_first = TME_SUNCG6_REG_FHC;
                   1320:   suncg6->tme_suncg6_bus_subregion_fhc_thc.tme_bus_subregion_address_last
                   1321:     = (TME_SUNCG6_REG_THC_UNKNOWN_0x0
                   1322:        + TME_SUNCG6_SIZ_THC
                   1323:        - 1);
                   1324:   suncg6->tme_suncg6_bus_handler_fhc_thc = _tme_suncg6_bus_cycle_fhc_thc;
                   1325: 
                   1326:   /* the FBC registers: */
                   1327:   suncg6->tme_suncg6_bus_subregion_fbc.tme_bus_subregion_address_first
                   1328:     = TME_SUNCG6_REG_FBC_GROUP0;
                   1329:   suncg6->tme_suncg6_bus_subregion_fbc.tme_bus_subregion_address_last
                   1330:     = TME_SUNCG6_REG_TEC_GROUP0 - 1;
                   1331:   suncg6->tme_suncg6_bus_handler_fbc = _tme_suncg6_bus_cycle_fbc;
                   1332: 
                   1333:   /* the TEC registers: */
                   1334:   suncg6->tme_suncg6_bus_subregion_tec.tme_bus_subregion_address_first
                   1335:     = TME_SUNCG6_REG_TEC_GROUP0;
                   1336:   suncg6->tme_suncg6_bus_subregion_tec.tme_bus_subregion_address_last
                   1337:     = (TME_SUNCG6_REG_TEC_GROUP0
                   1338:        + TME_SUNCG6_TEC_SIZE
                   1339:        - 1);
                   1340:   suncg6->tme_suncg6_bus_handler_tec = _tme_suncg6_bus_cycle_tec;
                   1341: 
                   1342:   /* the memory address: */
                   1343:   sunfb->tme_sunfb_bus_subregion_memory.tme_bus_subregion_address_first = TME_SUNFB_S4_OFFSET_MEMORY;
                   1344: 
                   1345:   /* if the generic initialization fails: */
                   1346:   rc = tme_sunfb_new(sunfb, args, _output);
                   1347:   if (rc) {
                   1348: 
                   1349:     /* free the sunfb structure and return the error: */
                   1350:     tme_free(sunfb);
                   1351:     return (rc);
                   1352:   }
                   1353: 
                   1354:   /* set the size in the initial FHC: */
                   1355:   fhc = suncg6->tme_suncg6_fhc;
                   1356:   fhc &= (TME_SUNCG6_FHC_ID_MASK
                   1357:          + TME_SUNCG6_FHC_REVISION_MASK);
                   1358:   switch (sunfb->tme_sunfb_size) {
                   1359:   default: assert(FALSE);
                   1360:   case TME_SUNFB_SIZE_1152_900: fhc += TME_SUNCG6_FHC_SIZE_1152_900; break;
                   1361:   case TME_SUNFB_SIZE_1024_768: fhc += TME_SUNCG6_FHC_SIZE_1024_768; break;
                   1362:   case TME_SUNFB_SIZE_1280_1024: fhc += TME_SUNCG6_FHC_SIZE_1280_1024; break;
                   1363:   case TME_SUNFB_SIZE_1600_1280: fhc += TME_SUNCG6_FHC_SIZE_1600_1280; break;
                   1364:   }
                   1365:   suncg6->tme_suncg6_fhc = fhc;
                   1366: 
                   1367:   /* save the size: */
                   1368:   suncg6->tme_suncg6_width = tme_sunfb_size_width(suncg6->tme_suncg6_sunfb.tme_sunfb_size);
                   1369:   suncg6->tme_suncg6_height = tme_sunfb_size_height(suncg6->tme_suncg6_sunfb.tme_sunfb_size);
                   1370: 
                   1371:   /* allocate the colormap arrays: */
                   1372:   cmap = tme_new0(tme_uint8_t, 256 * 3);
                   1373:   sunfb->tme_sunfb_cmap_g = &cmap[256 * 0];
                   1374:   sunfb->tme_sunfb_cmap_r = &cmap[256 * 1];
                   1375:   sunfb->tme_sunfb_cmap_b = &cmap[256 * 2];
                   1376:   sunfb->tme_sunfb_bt458.tme_bt458_cmap_g = sunfb->tme_sunfb_cmap_g;
                   1377:   sunfb->tme_sunfb_bt458.tme_bt458_cmap_r = sunfb->tme_sunfb_cmap_r;
                   1378:   sunfb->tme_sunfb_bt458.tme_bt458_cmap_b = sunfb->tme_sunfb_cmap_b;
                   1379: 
                   1380:   return (TME_OK);
                   1381: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.