|
|
1.1.1.3 root 1: /* $Id: sun-bwtwo.c,v 1.6 2009/11/08 17:03:58 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.3 root 37: _TME_RCSID("$Id: sun-bwtwo.c,v 1.6 2009/11/08 17:03:58 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:
1.1.1.4 ! root 95: #if 1
! 96: static int sunbw2_copy;
! 97: static int sunbw2_copy_addr;
! 98: int get_sunbw2_copy(void) { return sunbw2_copy; }
! 99: int get_sunbw2_copy_addr(void) { return sunbw2_copy_addr; }
! 100: #endif
! 101:
1.1 root 102: #ifdef TME_SUNBW2_DEBUG
103: #define TME_SUNBW2_LO_WIDTH (1152)
104: #define TME_SUNBW2_LO_HEIGHT (900)
105: static int
106: _tme_sunbw2_update_debug(struct tme_fb_connection *conn_fb)
107: {
108: struct tme_sunbw2 *sunbw2;
109: static int y = -1;
110: static int x;
111: unsigned long pixel;
112: unsigned int pixel_byte;
113: tme_uint8_t pixel_bit;
114: int box, box_y, box_x;
115:
116: sunbw2 = conn_fb->tme_fb_connection.tme_connection_element->tme_element_private;
117:
118: for (box = 0; box < 2; box++) {
119: if (y < 0) {
120: y = 16;
121: x = 0;
122: continue;
123: }
124: for (box_y = 0; box_y < 2; box_y++) {
125: for (box_x = 0; box_x < 2; box_x++) {
126: pixel = (((y + box_y)
127: * TME_SUNBW2_LO_WIDTH)
128: + x
129: + box_x);
130: pixel_byte = (pixel / 8);
131: pixel_bit = (0x80 >> (pixel % 8));
132: sunbw2->tme_sunbw2_fb_memory[pixel_byte] ^= pixel_bit;
133: }
134: }
135: if (box == 0) {
136: x += 2;
137: if (x == TME_SUNBW2_LO_WIDTH) {
138: x = 0;
139: y += 2;
140: if (y == TME_SUNBW2_LO_HEIGHT) {
141: y = 0;
142: }
143: }
144: }
145: }
146:
147: return (TME_OK);
148: }
149: #undef TME_SUNBW2_LO_WIDTH
150: #undef TME_SUNBW2_LO_HEIGHT
151: #endif /* TME_SUNBW2_DEBUG */
152:
153: /* the sunbw2 CSR bus cycle handler: */
154: static int
155: _tme_sunbw2_bus_cycle_csr(void *_sunbw2, struct tme_bus_cycle *cycle_init)
156: {
157: struct tme_sunbw2 *sunbw2;
158: tme_uint16_t csr_old, csr_new;
1.1.1.3 root 159: tme_bus_addr32_t undecoded;
1.1 root 160:
161: /* recover our data structure: */
162: sunbw2 = (struct tme_sunbw2 *) _sunbw2;
163:
164: /* lock the mutex: */
165: tme_mutex_lock(&sunbw2->tme_sunbw2_mutex);
166:
167: /* get the old CSR value: */
168: csr_old = tme_betoh_u16(sunbw2->tme_sunbw2_csr);
169:
170: /* the entire 2KB (one page's) worth of addresses at
171: tme_sunbw2_csr_address are all decoded (or, rather, not decoded)
172: as the CSR: */
173: undecoded
174: = (cycle_init->tme_bus_cycle_address
175: & (TME_SUNBW2_SIZ_CSR_PAGE - sizeof(sunbw2->tme_sunbw2_csr)));
176: cycle_init->tme_bus_cycle_address
177: -= undecoded;
178:
179: /* run the cycle: */
180: assert (cycle_init->tme_bus_cycle_address
181: >= sunbw2->tme_sunbw2_csr_address);
182: tme_bus_cycle_xfer_memory(cycle_init,
183: (((tme_uint8_t *) &sunbw2->tme_sunbw2_csr)
184: - sunbw2->tme_sunbw2_csr_address),
185: (sunbw2->tme_sunbw2_csr_address
186: + sizeof(sunbw2->tme_sunbw2_csr)
187: - 1));
188: cycle_init->tme_bus_cycle_address
189: += undecoded;
190:
191: /* get the new CSR value: */
192: csr_new = tme_betoh_u16(sunbw2->tme_sunbw2_csr);
193:
194: /* put back the unchanging bits: */
195: csr_new
196: = ((csr_new
197: & ~(TME_SUNBW2_CSR_INT_ACTIVE
198: | TME_SUNBW2_CSR_JUMPER_B
199: | TME_SUNBW2_CSR_JUMPER_A
200: | TME_SUNBW2_CSR_JUMPER_COLOR
201: | TME_SUNBW2_CSR_JUMPER_HIRES))
202: | (csr_old
203: & (TME_SUNBW2_CSR_INT_ACTIVE
204: | TME_SUNBW2_CSR_JUMPER_B
205: | TME_SUNBW2_CSR_JUMPER_A
206: | TME_SUNBW2_CSR_JUMPER_COLOR
207: | TME_SUNBW2_CSR_JUMPER_HIRES)));
208:
1.1.1.4 ! root 209: #if 0//brad
1.1 root 210: /* we do not support these bits: */
211: if (csr_new
212: & (TME_SUNBW2_CSR_ENABLE_COPY
213: | TME_SUNBW2_CSR_ENABLE_INT)) {
214: abort();
215: }
1.1.1.4 ! root 216: #else
! 217: if (csr_new & TME_SUNBW2_CSR_ENABLE_COPY) {
! 218: sunbw2_copy = 1;
! 219: sunbw2_copy_addr = (csr_new & TME_SUNBW2_CSR_COPYBASE_MASK) << 16;
! 220: } else
! 221: sunbw2_copy = 0;
! 222: #endif
1.1 root 223:
224: /* set the new CSR value: */
225: sunbw2->tme_sunbw2_csr = tme_htobe_u16(csr_new);
226:
227: /* unlock the mutex: */
228: tme_mutex_unlock(&sunbw2->tme_sunbw2_mutex);
229:
230: /* no faults: */
231: return (TME_OK);
232: }
233:
1.1.1.2 root 234: /* this sets the bwtwo type: */
235: static const char *
236: _tme_sunbw2_type_set(struct tme_sunfb *sunfb, const char *bw2_type_string)
1.1 root 237: {
238: struct tme_sunbw2 *sunbw2;
1.1.1.2 root 239: tme_uint32_t bw2_type;
1.1 root 240:
241: /* recover our data structure: */
1.1.1.2 root 242: sunbw2 = (struct tme_sunbw2 *) sunfb;
1.1 root 243:
1.1.1.2 root 244: /* see if this is a good type: */
245: bw2_type = TME_SUNBW2_TYPE_NULL;
246: if (TME_ARG_IS(bw2_type_string, "multibus")) {
247: bw2_type = TME_SUNBW2_TYPE_MULTIBUS;
1.1 root 248: }
1.1.1.2 root 249: else if (TME_ARG_IS(bw2_type_string, "old-onboard")) {
250: bw2_type = TME_SUNBW2_TYPE_OLD_ONBOARD;
1.1 root 251: }
1.1.1.2 root 252: else if (TME_ARG_IS(bw2_type_string, "onboard")) {
253: bw2_type = TME_SUNBW2_TYPE_ONBOARD;
1.1 root 254: }
1.1.1.2 root 255: else if (TME_ARG_IS(bw2_type_string, "P4")) {
256: bw2_type = TME_SUNBW2_TYPE_P4;
1.1 root 257: }
1.1.1.2 root 258: else if (TME_ARG_IS(bw2_type_string, "sbus")) {
259: bw2_type = TME_SUNBW2_TYPE_SBUS;
1.1 root 260: }
261:
1.1.1.2 root 262: /* set the new type: */
263: sunbw2->tme_sunbw2_type = bw2_type;
1.1 root 264:
1.1.1.2 root 265: /* assume the (relative) bus address of the first byte of displayed
266: framebuffer memory is zero: */
267: sunbw2->tme_sunbw2_bus_subregion_memory.tme_bus_subregion_address_first = 0;
1.1 root 268:
1.1.1.3 root 269: /* assume that we can use the unspecified interrupt: */
270: sunfb->tme_sunfb_bus_signal_int = TME_BUS_SIGNAL_INT_UNSPEC;
271:
1.1.1.2 root 272: /* dispatch on the new type: */
273: switch (bw2_type) {
1.1 root 274:
1.1.1.2 root 275: /* if this was a bad type, return a string of types: */
276: default: assert(FALSE);
277: case TME_SUNBW2_TYPE_NULL:
278: return ("multibus | old-onboard | onboard | P4 | sbus");
1.1 root 279:
1.1.1.2 root 280: case TME_SUNBW2_TYPE_MULTIBUS:
281: case TME_SUNBW2_TYPE_OLD_ONBOARD:
282:
283: /* set the addresses of the CSR bus subregion: */
284: sunbw2->tme_sunbw2_csr_address
285: = (bw2_type == TME_SUNBW2_TYPE_MULTIBUS
286: ? TME_SUNBW2_REG_CSR_MULTIBUS
287: : TME_SUNBW2_REG_CSR_OLD_ONBOARD);
288: sunbw2->tme_sunbw2_bus_subregion_regs.tme_bus_subregion_address_last
289: = (sunbw2->tme_sunbw2_csr_address
290: + TME_SUNBW2_SIZ_CSR_PAGE
291: - 1);
1.1 root 292:
1.1.1.2 root 293: /* set the CSR bus cycle handler: */
294: sunfb->tme_sunfb_bus_handler_regs = _tme_sunbw2_bus_cycle_csr;
1.1 root 295:
1.1.1.2 root 296: /* the original Multibus bwtwo and onboard bwtwo only support
297: 1152x900 and 1024x1024: */
298: sunfb->tme_sunfb_size
299: = (TME_SUNFB_SIZE_1152_900
300: | TME_SUNFB_SIZE_1024_1024);
301: break;
1.1 root 302:
1.1.1.2 root 303: case TME_SUNBW2_TYPE_ONBOARD:
1.1 root 304:
1.1.1.2 root 305: /* the onboard bwtwo doesn't have any CSR: */
306: sunfb->tme_sunfb_bus_handler_regs = NULL;
307:
308: /* the sizes supported by a CSR-less bwtwo appear to depend on the
309: actual model; we assume the user knows what he is doing: */
310: sunfb->tme_sunfb_size = (TME_SUNFB_SIZE_NULL - 1);
311: break;
1.1 root 312:
1.1.1.2 root 313: case TME_SUNBW2_TYPE_P4:
1.1 root 314:
1.1.1.2 root 315: /* set our initial P4 register: */
316: sunfb->tme_sunfb_p4 = tme_htobe_u32(TME_SUNFB_P4_ID_BWTWO);
1.1 root 317:
1.1.1.2 root 318: /* set the P4 register bus cycle handler: */
319: sunfb->tme_sunfb_bus_handler_regs = tme_sunfb_bus_cycle_p4;
1.1 root 320:
1.1.1.2 root 321: /* we support the default P4 framebuffer sizes: */
322: sunfb->tme_sunfb_size = 0;
1.1 root 323:
1.1.1.2 root 324: /* the framebuffer memory begins at a fixed offset after the P4 register: */
325: sunbw2->tme_sunbw2_bus_subregion_memory.tme_bus_subregion_address_first
326: = TME_SUNFB_P4_OFFSET_BITMAP;
1.1 root 327:
1.1.1.2 root 328: break;
1.1 root 329:
1.1.1.2 root 330: case TME_SUNBW2_TYPE_SBUS:
1.1 root 331:
1.1.1.2 root 332: /* set the S4 register bus cycle handler: */
333: sunfb->tme_sunfb_bus_handler_regs = tme_sunfb_bus_cycle_s4;
1.1 root 334:
1.1.1.2 root 335: /* we support the default S4 framebuffer sizes: */
336: sunfb->tme_sunfb_size = 0;
1.1 root 337:
1.1.1.2 root 338: /* we use the default S4 memory address: */
339: sunbw2->tme_sunbw2_bus_subregion_memory.tme_bus_subregion_address_first = 0;
1.1 root 340:
1.1.1.3 root 341: /* the SBus bwtwo uses priority seven interrupts: */
342: sunfb->tme_sunfb_bus_signal_int = TME_BUS_SIGNAL_INT(7);
343:
1.1.1.2 root 344: break;
1.1 root 345: }
346:
1.1.1.2 root 347: /* success: */
348: return (NULL);
1.1 root 349: }
350:
351: /* the new sun bwtwo function: */
352: int
353: tme_sun_bwtwo(struct tme_element *element, const char * const *args, char **_output)
354: {
355: struct tme_sunbw2 *sunbw2;
1.1.1.2 root 356: int rc;
1.1 root 357:
358: /* start the sunbw2 structure: */
359: sunbw2 = tme_new0(struct tme_sunbw2, 1);
1.1.1.2 root 360: sunbw2->tme_sunbw2_sunfb.tme_sunfb_element = element;
1.1 root 361:
1.1.1.2 root 362: /* initialize the sunfb structure: */
363: sunbw2->tme_sunbw2_sunfb.tme_sunfb_class = TME_FB_XLAT_CLASS_MONOCHROME;
364: sunbw2->tme_sunbw2_sunfb.tme_sunfb_depth = 1;
365: sunbw2->tme_sunbw2_sunfb.tme_sunfb_type_set = _tme_sunbw2_type_set;
366:
367: /* if the generic initialization fails: */
368: rc = tme_sunfb_new(&sunbw2->tme_sunbw2_sunfb, args, _output);
369: if (rc) {
1.1 root 370:
1.1.1.2 root 371: /* free the sunfb structure and return the error: */
372: tme_free(sunbw2);
373: return (rc);
1.1 root 374: }
375:
376: /* dispatch on the bwtwo type: */
1.1.1.2 root 377: switch (sunbw2->tme_sunbw2_type) {
378: default: break;
1.1 root 379: case TME_SUNBW2_TYPE_MULTIBUS:
380: case TME_SUNBW2_TYPE_OLD_ONBOARD:
381:
382: /* set our initial CSR: */
383: sunbw2->tme_sunbw2_csr
384: = tme_htobe_u16(TME_SUNBW2_CSR_ENABLE_VIDEO
1.1.1.2 root 385: | (sunbw2->tme_sunbw2_sunfb.tme_sunfb_size == TME_SUNFB_SIZE_1024_1024
1.1 root 386: ? TME_SUNBW2_CSR_JUMPER_HIRES
387: : 0));
388:
389: break;
390: }
391:
392: return (TME_OK);
393: }
394:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.