|
|
1.1.1.2 ! root 1: /* $Id: sun-bwtwo.c,v 1.4 2007/02/15 02:05:12 fredette Exp $ */ 1.1 root 2: 3: /* machine/sun/sun-bwtwo.c - Sun bwtwo emulation: */ 4: 5: /* 1.1.1.2 ! root 6: * Copyright (c) 2003, 2004, 2006 Matt Fredette 1.1 root 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> 1.1.1.2 ! root 37: _TME_RCSID("$Id: sun-bwtwo.c,v 1.4 2007/02/15 02:05:12 fredette Exp $"); 1.1 root 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: /* bwtwo types: */ 48: #define TME_SUNBW2_TYPE_NULL (0) 49: #define TME_SUNBW2_TYPE_MULTIBUS (1) 50: #define TME_SUNBW2_TYPE_OLD_ONBOARD (2) 51: #define TME_SUNBW2_TYPE_ONBOARD (3) 52: #define TME_SUNBW2_TYPE_P4 (4) 1.1.1.2 ! root 53: #define TME_SUNBW2_TYPE_SBUS (5) 1.1 root 54: 55: /* register offsets and sizes: */ 56: #define TME_SUNBW2_REG_CSR_MULTIBUS (0x81800) 57: #define TME_SUNBW2_REG_CSR_OLD_ONBOARD (0x20000) 58: #define TME_SUNBW2_SIZ_CSR (0x00002) 59: #define TME_SUNBW2_SIZ_CSR_PAGE (0x00800) 60: 61: /* the bits in the Multibus and old-onboard Control/Status register: */ 62: #define TME_SUNBW2_CSR_ENABLE_VIDEO (0x8000) /* enable video */ 63: #define TME_SUNBW2_CSR_ENABLE_COPY (0x4000) /* enable copy mode */ 64: #define TME_SUNBW2_CSR_ENABLE_INT (0x2000) /* interrupt enable */ 65: #define TME_SUNBW2_CSR_INT_ACTIVE (0x1000) /* interrupt is active */ 66: #define TME_SUNBW2_CSR_JUMPER_B (0x0800) /* jumper B */ 67: #define TME_SUNBW2_CSR_JUMPER_A (0x0400) /* jumper A */ 68: #define TME_SUNBW2_CSR_JUMPER_COLOR (0x0200) /* jumper color */ 69: #define TME_SUNBW2_CSR_JUMPER_HIRES (0x0100) /* jumper hires */ 70: #define TME_SUNBW2_CSR_COPYBASE_MASK (0x007E) /* copybase mask */ 71: 72: #if 0 73: #define TME_SUNBW2_DEBUG 74: #endif 75: 76: /* structures: */ 77: 78: /* the card: */ 79: struct tme_sunbw2 { 80: 1.1.1.2 ! root 81: /* our generic Sun framebuffer: */ ! 82: struct tme_sunfb tme_sunbw2_sunfb; ! 83: #define tme_sunbw2_mutex tme_sunbw2_sunfb.tme_sunfb_mutex ! 84: #define tme_sunbw2_bus_subregion_memory tme_sunbw2_sunfb.tme_sunfb_bus_subregion_memory ! 85: #define tme_sunbw2_bus_subregion_regs tme_sunbw2_sunfb.tme_sunfb_bus_subregion_regs ! 86: #define tme_sunbw2_csr_address tme_sunbw2_bus_subregion_regs.tme_bus_subregion_address_first 1.1 root 87: 88: /* the type of the bwtwo: */ 89: tme_uint32_t tme_sunbw2_type; 90: 91: /* our csr: */ 92: tme_uint16_t tme_sunbw2_csr; 93: }; 94: 95: #ifdef TME_SUNBW2_DEBUG 96: #define TME_SUNBW2_LO_WIDTH (1152) 97: #define TME_SUNBW2_LO_HEIGHT (900) 98: static int 99: _tme_sunbw2_update_debug(struct tme_fb_connection *conn_fb) 100: { 101: struct tme_sunbw2 *sunbw2; 102: static int y = -1; 103: static int x; 104: unsigned long pixel; 105: unsigned int pixel_byte; 106: tme_uint8_t pixel_bit; 107: int box, box_y, box_x; 108: 109: sunbw2 = conn_fb->tme_fb_connection.tme_connection_element->tme_element_private; 110: 111: for (box = 0; box < 2; box++) { 112: if (y < 0) { 113: y = 16; 114: x = 0; 115: continue; 116: } 117: for (box_y = 0; box_y < 2; box_y++) { 118: for (box_x = 0; box_x < 2; box_x++) { 119: pixel = (((y + box_y) 120: * TME_SUNBW2_LO_WIDTH) 121: + x 122: + box_x); 123: pixel_byte = (pixel / 8); 124: pixel_bit = (0x80 >> (pixel % 8)); 125: sunbw2->tme_sunbw2_fb_memory[pixel_byte] ^= pixel_bit; 126: } 127: } 128: if (box == 0) { 129: x += 2; 130: if (x == TME_SUNBW2_LO_WIDTH) { 131: x = 0; 132: y += 2; 133: if (y == TME_SUNBW2_LO_HEIGHT) { 134: y = 0; 135: } 136: } 137: } 138: } 139: 140: return (TME_OK); 141: } 142: #undef TME_SUNBW2_LO_WIDTH 143: #undef TME_SUNBW2_LO_HEIGHT 144: #endif /* TME_SUNBW2_DEBUG */ 145: 146: /* the sunbw2 CSR bus cycle handler: */ 147: static int 148: _tme_sunbw2_bus_cycle_csr(void *_sunbw2, struct tme_bus_cycle *cycle_init) 149: { 150: struct tme_sunbw2 *sunbw2; 151: tme_uint16_t csr_old, csr_new; 152: tme_bus_addr_t undecoded; 153: 154: /* recover our data structure: */ 155: sunbw2 = (struct tme_sunbw2 *) _sunbw2; 156: 157: /* lock the mutex: */ 158: tme_mutex_lock(&sunbw2->tme_sunbw2_mutex); 159: 160: /* get the old CSR value: */ 161: csr_old = tme_betoh_u16(sunbw2->tme_sunbw2_csr); 162: 163: /* the entire 2KB (one page's) worth of addresses at 164: tme_sunbw2_csr_address are all decoded (or, rather, not decoded) 165: as the CSR: */ 166: undecoded 167: = (cycle_init->tme_bus_cycle_address 168: & (TME_SUNBW2_SIZ_CSR_PAGE - sizeof(sunbw2->tme_sunbw2_csr))); 169: cycle_init->tme_bus_cycle_address 170: -= undecoded; 171: 172: /* run the cycle: */ 173: assert (cycle_init->tme_bus_cycle_address 174: >= sunbw2->tme_sunbw2_csr_address); 175: tme_bus_cycle_xfer_memory(cycle_init, 176: (((tme_uint8_t *) &sunbw2->tme_sunbw2_csr) 177: - sunbw2->tme_sunbw2_csr_address), 178: (sunbw2->tme_sunbw2_csr_address 179: + sizeof(sunbw2->tme_sunbw2_csr) 180: - 1)); 181: cycle_init->tme_bus_cycle_address 182: += undecoded; 183: 184: /* get the new CSR value: */ 185: csr_new = tme_betoh_u16(sunbw2->tme_sunbw2_csr); 186: 187: /* put back the unchanging bits: */ 188: csr_new 189: = ((csr_new 190: & ~(TME_SUNBW2_CSR_INT_ACTIVE 191: | TME_SUNBW2_CSR_JUMPER_B 192: | TME_SUNBW2_CSR_JUMPER_A 193: | TME_SUNBW2_CSR_JUMPER_COLOR 194: | TME_SUNBW2_CSR_JUMPER_HIRES)) 195: | (csr_old 196: & (TME_SUNBW2_CSR_INT_ACTIVE 197: | TME_SUNBW2_CSR_JUMPER_B 198: | TME_SUNBW2_CSR_JUMPER_A 199: | TME_SUNBW2_CSR_JUMPER_COLOR 200: | TME_SUNBW2_CSR_JUMPER_HIRES))); 201: 202: /* we do not support these bits: */ 203: if (csr_new 204: & (TME_SUNBW2_CSR_ENABLE_COPY 205: | TME_SUNBW2_CSR_ENABLE_INT)) { 206: abort(); 207: } 208: 209: /* set the new CSR value: */ 210: sunbw2->tme_sunbw2_csr = tme_htobe_u16(csr_new); 211: 212: /* unlock the mutex: */ 213: tme_mutex_unlock(&sunbw2->tme_sunbw2_mutex); 214: 215: /* no faults: */ 216: return (TME_OK); 217: } 218: 1.1.1.2 ! root 219: /* this sets the bwtwo type: */ ! 220: static const char * ! 221: _tme_sunbw2_type_set(struct tme_sunfb *sunfb, const char *bw2_type_string) 1.1 root 222: { 223: struct tme_sunbw2 *sunbw2; 1.1.1.2 ! root 224: tme_uint32_t bw2_type; 1.1 root 225: 226: /* recover our data structure: */ 1.1.1.2 ! root 227: sunbw2 = (struct tme_sunbw2 *) sunfb; 1.1 root 228: 1.1.1.2 ! root 229: /* see if this is a good type: */ ! 230: bw2_type = TME_SUNBW2_TYPE_NULL; ! 231: if (TME_ARG_IS(bw2_type_string, "multibus")) { ! 232: bw2_type = TME_SUNBW2_TYPE_MULTIBUS; 1.1 root 233: } 1.1.1.2 ! root 234: else if (TME_ARG_IS(bw2_type_string, "old-onboard")) { ! 235: bw2_type = TME_SUNBW2_TYPE_OLD_ONBOARD; 1.1 root 236: } 1.1.1.2 ! root 237: else if (TME_ARG_IS(bw2_type_string, "onboard")) { ! 238: bw2_type = TME_SUNBW2_TYPE_ONBOARD; 1.1 root 239: } 1.1.1.2 ! root 240: else if (TME_ARG_IS(bw2_type_string, "P4")) { ! 241: bw2_type = TME_SUNBW2_TYPE_P4; 1.1 root 242: } 1.1.1.2 ! root 243: else if (TME_ARG_IS(bw2_type_string, "sbus")) { ! 244: bw2_type = TME_SUNBW2_TYPE_SBUS; 1.1 root 245: } 246: 1.1.1.2 ! root 247: /* set the new type: */ ! 248: sunbw2->tme_sunbw2_type = bw2_type; 1.1 root 249: 1.1.1.2 ! root 250: /* assume the (relative) bus address of the first byte of displayed ! 251: framebuffer memory is zero: */ ! 252: sunbw2->tme_sunbw2_bus_subregion_memory.tme_bus_subregion_address_first = 0; 1.1 root 253: 1.1.1.2 ! root 254: /* dispatch on the new type: */ ! 255: switch (bw2_type) { 1.1 root 256: 1.1.1.2 ! root 257: /* if this was a bad type, return a string of types: */ ! 258: default: assert(FALSE); ! 259: case TME_SUNBW2_TYPE_NULL: ! 260: return ("multibus | old-onboard | onboard | P4 | sbus"); 1.1 root 261: 1.1.1.2 ! root 262: case TME_SUNBW2_TYPE_MULTIBUS: ! 263: case TME_SUNBW2_TYPE_OLD_ONBOARD: ! 264: ! 265: /* set the addresses of the CSR bus subregion: */ ! 266: sunbw2->tme_sunbw2_csr_address ! 267: = (bw2_type == TME_SUNBW2_TYPE_MULTIBUS ! 268: ? TME_SUNBW2_REG_CSR_MULTIBUS ! 269: : TME_SUNBW2_REG_CSR_OLD_ONBOARD); ! 270: sunbw2->tme_sunbw2_bus_subregion_regs.tme_bus_subregion_address_last ! 271: = (sunbw2->tme_sunbw2_csr_address ! 272: + TME_SUNBW2_SIZ_CSR_PAGE ! 273: - 1); 1.1 root 274: 1.1.1.2 ! root 275: /* set the CSR bus cycle handler: */ ! 276: sunfb->tme_sunfb_bus_handler_regs = _tme_sunbw2_bus_cycle_csr; 1.1 root 277: 1.1.1.2 ! root 278: /* the original Multibus bwtwo and onboard bwtwo only support ! 279: 1152x900 and 1024x1024: */ ! 280: sunfb->tme_sunfb_size ! 281: = (TME_SUNFB_SIZE_1152_900 ! 282: | TME_SUNFB_SIZE_1024_1024); ! 283: break; 1.1 root 284: 1.1.1.2 ! root 285: case TME_SUNBW2_TYPE_ONBOARD: 1.1 root 286: 1.1.1.2 ! root 287: /* the onboard bwtwo doesn't have any CSR: */ ! 288: sunfb->tme_sunfb_bus_handler_regs = NULL; ! 289: ! 290: /* the sizes supported by a CSR-less bwtwo appear to depend on the ! 291: actual model; we assume the user knows what he is doing: */ ! 292: sunfb->tme_sunfb_size = (TME_SUNFB_SIZE_NULL - 1); ! 293: break; 1.1 root 294: 1.1.1.2 ! root 295: case TME_SUNBW2_TYPE_P4: 1.1 root 296: 1.1.1.2 ! root 297: /* set our initial P4 register: */ ! 298: sunfb->tme_sunfb_p4 = tme_htobe_u32(TME_SUNFB_P4_ID_BWTWO); 1.1 root 299: 1.1.1.2 ! root 300: /* set the P4 register bus cycle handler: */ ! 301: sunfb->tme_sunfb_bus_handler_regs = tme_sunfb_bus_cycle_p4; 1.1 root 302: 1.1.1.2 ! root 303: /* we support the default P4 framebuffer sizes: */ ! 304: sunfb->tme_sunfb_size = 0; 1.1 root 305: 1.1.1.2 ! root 306: /* the framebuffer memory begins at a fixed offset after the P4 register: */ ! 307: sunbw2->tme_sunbw2_bus_subregion_memory.tme_bus_subregion_address_first ! 308: = TME_SUNFB_P4_OFFSET_BITMAP; 1.1 root 309: 1.1.1.2 ! root 310: break; 1.1 root 311: 1.1.1.2 ! root 312: case TME_SUNBW2_TYPE_SBUS: 1.1 root 313: 1.1.1.2 ! root 314: /* set the S4 register bus cycle handler: */ ! 315: sunfb->tme_sunfb_bus_handler_regs = tme_sunfb_bus_cycle_s4; 1.1 root 316: 1.1.1.2 ! root 317: /* we support the default S4 framebuffer sizes: */ ! 318: sunfb->tme_sunfb_size = 0; 1.1 root 319: 1.1.1.2 ! root 320: /* we use the default S4 memory address: */ ! 321: sunbw2->tme_sunbw2_bus_subregion_memory.tme_bus_subregion_address_first = 0; 1.1 root 322: 1.1.1.2 ! root 323: break; 1.1 root 324: } 325: 1.1.1.2 ! root 326: /* success: */ ! 327: return (NULL); 1.1 root 328: } 329: 330: /* the new sun bwtwo function: */ 331: int 332: tme_sun_bwtwo(struct tme_element *element, const char * const *args, char **_output) 333: { 334: struct tme_sunbw2 *sunbw2; 1.1.1.2 ! root 335: int rc; 1.1 root 336: 337: /* start the sunbw2 structure: */ 338: sunbw2 = tme_new0(struct tme_sunbw2, 1); 1.1.1.2 ! root 339: sunbw2->tme_sunbw2_sunfb.tme_sunfb_element = element; 1.1 root 340: 1.1.1.2 ! root 341: /* initialize the sunfb structure: */ ! 342: sunbw2->tme_sunbw2_sunfb.tme_sunfb_class = TME_FB_XLAT_CLASS_MONOCHROME; ! 343: sunbw2->tme_sunbw2_sunfb.tme_sunfb_depth = 1; ! 344: sunbw2->tme_sunbw2_sunfb.tme_sunfb_type_set = _tme_sunbw2_type_set; ! 345: ! 346: /* if the generic initialization fails: */ ! 347: rc = tme_sunfb_new(&sunbw2->tme_sunbw2_sunfb, args, _output); ! 348: if (rc) { 1.1 root 349: 1.1.1.2 ! root 350: /* free the sunfb structure and return the error: */ ! 351: tme_free(sunbw2); ! 352: return (rc); 1.1 root 353: } 354: 355: /* dispatch on the bwtwo type: */ 1.1.1.2 ! root 356: switch (sunbw2->tme_sunbw2_type) { ! 357: default: break; 1.1 root 358: case TME_SUNBW2_TYPE_MULTIBUS: 359: case TME_SUNBW2_TYPE_OLD_ONBOARD: 360: 361: /* set our initial CSR: */ 362: sunbw2->tme_sunbw2_csr 363: = tme_htobe_u16(TME_SUNBW2_CSR_ENABLE_VIDEO 1.1.1.2 ! root 364: | (sunbw2->tme_sunbw2_sunfb.tme_sunfb_size == TME_SUNFB_SIZE_1024_1024 1.1 root 365: ? TME_SUNBW2_CSR_JUMPER_HIRES 366: : 0)); 367: 368: break; 369: } 370: 371: return (TME_OK); 372: } 373:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.