|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.