1 /* $OpenBSD: omrasops1.c,v 1.4 2021/07/31 05:22:36 aoyama Exp $ */ 2 3 /* 4 * Copyright (c) 2005, Miodrag Vallat. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 /* 30 * Copyright (c) 1996 Jason R. Thorpe. All rights reserved. 31 * Copyright (c) 1991 University of Utah. 32 * Copyright (c) 1990, 1993 33 * The Regents of the University of California. All rights reserved. 34 * 35 * This code is derived from software contributed to Berkeley by 36 * the Systems Programming Group of the University of Utah Computer 37 * Science Department and Mark Davies of the Department of Computer 38 * Science, Victoria University of Wellington, New Zealand. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. Neither the name of the University nor the names of its contributors 49 * may be used to endorse or promote products derived from this software 50 * without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * SUCH DAMAGE. 63 * 64 * from: Utah $Hdr: grf_hy.c 1.2 93/08/13$ 65 * 66 * @(#)grf_hy.c 8.4 (Berkeley) 1/12/94 67 */ 68 69 /* 70 * Graphics routines for OMRON LUNA 1bpp and 4bpp frame buffer. 71 * On LUNA's frame buffer, pixels are not byte-addressed. 72 * 73 * Based on src/sys/arch/hp300/dev/diofb_mono.c 74 */ 75 76 #include <sys/param.h> 77 #include <sys/systm.h> 78 79 #include <dev/wscons/wsconsio.h> 80 #include <dev/wscons/wsdisplayvar.h> 81 #include <dev/rasops/rasops.h> 82 #include <dev/rasops/rasops_masks.h> 83 84 #include <luna88k/dev/maskbits.h> 85 #include <luna88k/dev/omrasops.h> 86 87 #include <machine/board.h> 88 #define OMFB_FB_WADDR (BMAP_BMP + 8) /* common plane */ 89 90 /* prototypes */ 91 int om1_windowmove(struct rasops_info *, u_int16_t, u_int16_t, 92 u_int16_t, u_int16_t, u_int16_t, u_int16_t, int16_t, 93 int16_t /* ignored */); 94 int om4_windowmove(struct rasops_info *, u_int16_t, u_int16_t, 95 u_int16_t, u_int16_t, u_int16_t, u_int16_t, int16_t, 96 int16_t /* ignored */); 97 98 /* 99 * Block-move function - 1bpp version 100 */ 101 int 102 om1_windowmove(struct rasops_info *ri, u_int16_t sx, u_int16_t sy, 103 u_int16_t dx, u_int16_t dy, u_int16_t cx, u_int16_t cy, int16_t rop, 104 int16_t planemask /* ignored */) 105 { 106 int width; /* add to get to same position in next line */ 107 108 u_int32_t *psrcLine, *pdstLine; 109 /* pointers to line with current src and dst */ 110 u_int32_t *psrc; /* pointer to current src longword */ 111 u_int32_t *pdst; /* pointer to current dst longword */ 112 113 /* following used for looping through a line */ 114 u_int32_t startmask, endmask; /* masks for writing ends of dst */ 115 int nlMiddle; /* whole longwords in dst */ 116 int nl; /* temp copy of nlMiddle */ 117 int xoffSrc; /* offset (>= 0, < 32) from which to 118 fetch whole longwords fetched in src */ 119 int nstart; /* number of ragged bits at start of dst */ 120 int nend; /* number of ragged bits at end of dst */ 121 int srcStartOver; /* pulling nstart bits from src 122 overflows into the next word? */ 123 124 width = ri->ri_stride / 4; /* convert to number in longword */ 125 126 if (sy < dy) { /* start at last scanline of rectangle */ 127 psrcLine = ((u_int32_t *)OMFB_FB_WADDR) 128 + ((sy + cy - 1) * width); 129 pdstLine = ((u_int32_t *)OMFB_FB_WADDR) 130 + ((dy + cy - 1) * width); 131 width = -width; 132 } else { /* start at first scanline */ 133 psrcLine = ((u_int32_t *)OMFB_FB_WADDR) + (sy * width); 134 pdstLine = ((u_int32_t *)OMFB_FB_WADDR) + (dy * width); 135 } 136 137 /* x direction doesn't matter for < 1 longword */ 138 if (cx <= 32) { 139 int srcBit, dstBit; /* bit offset of src and dst */ 140 141 pdstLine += (dx >> 5); 142 psrcLine += (sx >> 5); 143 psrc = psrcLine; 144 pdst = pdstLine; 145 146 srcBit = sx & 0x1f; 147 dstBit = dx & 0x1f; 148 149 while (cy--) { 150 getandputrop(P0(psrc), srcBit, dstBit, cx, P0(pdst), rop); 151 pdst += width; 152 psrc += width; 153 } 154 } else { 155 maskbits(dx, cx, startmask, endmask, nlMiddle); 156 if (startmask) 157 nstart = 32 - (dx & 0x1f); 158 else 159 nstart = 0; 160 if (endmask) 161 nend = (dx + cx) & 0x1f; 162 else 163 nend = 0; 164 165 xoffSrc = ((sx & 0x1f) + nstart) & 0x1f; 166 srcStartOver = ((sx & 0x1f) + nstart) > 31; 167 168 if (sx >= dx) { /* move left to right */ 169 pdstLine += (dx >> 5); 170 psrcLine += (sx >> 5); 171 172 while (cy--) { 173 psrc = psrcLine; 174 pdst = pdstLine; 175 176 if (startmask) { 177 getandputrop(P0(psrc), (sx & 0x1f), 178 (dx & 0x1f), nstart, P0(pdst), rop); 179 pdst++; 180 if (srcStartOver) 181 psrc++; 182 } 183 184 /* special case for aligned operations */ 185 if (xoffSrc == 0) { 186 nl = nlMiddle; 187 while (nl--) { 188 if (rop == RR_CLEAR) 189 *P0(pdst) = 0; 190 else 191 *P0(pdst) = *P0(psrc); 192 psrc++; 193 pdst++; 194 } 195 } else { 196 nl = nlMiddle + 1; 197 while (--nl) { 198 if (rop == RR_CLEAR) 199 *P0(pdst) = 0; 200 else 201 getunalignedword(P0(psrc), 202 xoffSrc, *P0(pdst)); 203 pdst++; 204 psrc++; 205 } 206 } 207 208 if (endmask) { 209 getandputrop(P0(psrc), xoffSrc, 0, nend, 210 P0(pdst), rop); 211 } 212 213 pdstLine += width; 214 psrcLine += width; 215 } 216 } else { /* move right to left */ 217 pdstLine += ((dx + cx) >> 5); 218 psrcLine += ((sx + cx) >> 5); 219 /* 220 * If fetch of last partial bits from source crosses 221 * a longword boundary, start at the previous longword 222 */ 223 if (xoffSrc + nend >= 32) 224 --psrcLine; 225 226 while (cy--) { 227 psrc = psrcLine; 228 pdst = pdstLine; 229 230 if (endmask) { 231 getandputrop(P0(psrc), xoffSrc, 0, nend, 232 P0(pdst), rop); 233 } 234 235 nl = nlMiddle + 1; 236 while (--nl) { 237 --psrc; 238 --pdst; 239 if (rop == RR_CLEAR) 240 *P0(pdst) = 0; 241 else 242 getunalignedword(P0(psrc), xoffSrc, 243 *P0(pdst)); 244 } 245 246 if (startmask) { 247 if (srcStartOver) 248 --psrc; 249 --pdst; 250 getandputrop(P0(psrc), (sx & 0x1f), 251 (dx & 0x1f), nstart, P0(pdst), rop); 252 } 253 254 pdstLine += width; 255 psrcLine += width; 256 } 257 } 258 } 259 260 return (0); 261 } 262 263 /* 264 * Block-move function - 4bpp version 265 */ 266 int 267 om4_windowmove(struct rasops_info *ri, u_int16_t sx, u_int16_t sy, 268 u_int16_t dx, u_int16_t dy, u_int16_t cx, u_int16_t cy, int16_t rop, 269 int16_t planemask /* ignored */) 270 { 271 int width; /* add to get to same position in next line */ 272 273 u_int32_t *psrcLine, *pdstLine; 274 /* pointers to line with current src and dst */ 275 u_int32_t *psrc; /* pointer to current src longword */ 276 u_int32_t *pdst; /* pointer to current dst longword */ 277 278 /* following used for looping through a line */ 279 u_int32_t startmask, endmask; /* masks for writing ends of dst */ 280 int nlMiddle; /* whole longwords in dst */ 281 int nl; /* temp copy of nlMiddle */ 282 int xoffSrc; /* offset (>= 0, < 32) from which to 283 fetch whole longwords fetched in src */ 284 int nstart; /* number of ragged bits at start of dst */ 285 int nend; /* number of ragged bits at end of dst */ 286 int srcStartOver; /* pulling nstart bits from src 287 overflows into the next word? */ 288 289 width = ri->ri_stride / 4; /* convert to number in longword */ 290 291 if (sy < dy) { /* start at last scanline of rectangle */ 292 psrcLine = ((u_int32_t *)OMFB_FB_WADDR) 293 + ((sy + cy - 1) * width); 294 pdstLine = ((u_int32_t *)OMFB_FB_WADDR) 295 + ((dy + cy - 1) * width); 296 width = -width; 297 } else { /* start at first scanline */ 298 psrcLine = ((u_int32_t *)OMFB_FB_WADDR) + (sy * width); 299 pdstLine = ((u_int32_t *)OMFB_FB_WADDR) + (dy * width); 300 } 301 302 /* x direction doesn't matter for < 1 longword */ 303 if (cx <= 32) { 304 int srcBit, dstBit; /* bit offset of src and dst */ 305 306 pdstLine += (dx >> 5); 307 psrcLine += (sx >> 5); 308 psrc = psrcLine; 309 pdst = pdstLine; 310 311 srcBit = sx & 0x1f; 312 dstBit = dx & 0x1f; 313 314 while (cy--) { 315 getandputrop(P0(psrc), srcBit, dstBit, cx, P0(pdst), rop); 316 getandputrop(P1(psrc), srcBit, dstBit, cx, P1(pdst), rop); 317 getandputrop(P2(psrc), srcBit, dstBit, cx, P2(pdst), rop); 318 getandputrop(P3(psrc), srcBit, dstBit, cx, P3(pdst), rop); 319 pdst += width; 320 psrc += width; 321 } 322 } else { 323 maskbits(dx, cx, startmask, endmask, nlMiddle); 324 if (startmask) 325 nstart = 32 - (dx & 0x1f); 326 else 327 nstart = 0; 328 if (endmask) 329 nend = (dx + cx) & 0x1f; 330 else 331 nend = 0; 332 333 xoffSrc = ((sx & 0x1f) + nstart) & 0x1f; 334 srcStartOver = ((sx & 0x1f) + nstart) > 31; 335 336 if (sx >= dx) { /* move left to right */ 337 pdstLine += (dx >> 5); 338 psrcLine += (sx >> 5); 339 340 while (cy--) { 341 psrc = psrcLine; 342 pdst = pdstLine; 343 344 if (startmask) { 345 getandputrop(P0(psrc), (sx & 0x1f), 346 (dx & 0x1f), nstart, P0(pdst), rop); 347 getandputrop(P1(psrc), (sx & 0x1f), 348 (dx & 0x1f), nstart, P1(pdst), rop); 349 getandputrop(P2(psrc), (sx & 0x1f), 350 (dx & 0x1f), nstart, P2(pdst), rop); 351 getandputrop(P3(psrc), (sx & 0x1f), 352 (dx & 0x1f), nstart, P3(pdst), rop); 353 pdst++; 354 if (srcStartOver) 355 psrc++; 356 } 357 358 /* special case for aligned operations */ 359 if (xoffSrc == 0) { 360 nl = nlMiddle; 361 while (nl--) { 362 if (rop == RR_CLEAR) { 363 *P0(pdst) = 0; 364 *P1(pdst) = 0; 365 *P2(pdst) = 0; 366 *P3(pdst) = 0; 367 } else { 368 *P0(pdst) = *P0(psrc); 369 *P1(pdst) = *P1(psrc); 370 *P2(pdst) = *P2(psrc); 371 *P3(pdst) = *P3(psrc); 372 } 373 psrc++; 374 pdst++; 375 } 376 } else { 377 nl = nlMiddle + 1; 378 while (--nl) { 379 if (rop == RR_CLEAR) { 380 *P0(pdst) = 0; 381 *P1(pdst) = 0; 382 *P2(pdst) = 0; 383 *P3(pdst) = 0; 384 } else { 385 getunalignedword(P0(psrc), 386 xoffSrc, *P0(pdst)); 387 getunalignedword(P1(psrc), 388 xoffSrc, *P1(pdst)); 389 getunalignedword(P2(psrc), 390 xoffSrc, *P2(pdst)); 391 getunalignedword(P3(psrc), 392 xoffSrc, *P3(pdst)); 393 } 394 pdst++; 395 psrc++; 396 } 397 } 398 399 if (endmask) { 400 getandputrop(P0(psrc), xoffSrc, 0, nend, 401 P0(pdst), rop); 402 getandputrop(P1(psrc), xoffSrc, 0, nend, 403 P1(pdst), rop); 404 getandputrop(P2(psrc), xoffSrc, 0, nend, 405 P2(pdst), rop); 406 getandputrop(P3(psrc), xoffSrc, 0, nend, 407 P3(pdst), rop); 408 } 409 410 pdstLine += width; 411 psrcLine += width; 412 } 413 } else { /* move right to left */ 414 pdstLine += ((dx + cx) >> 5); 415 psrcLine += ((sx + cx) >> 5); 416 /* 417 * If fetch of last partial bits from source crosses 418 * a longword boundary, start at the previous longword 419 */ 420 if (xoffSrc + nend >= 32) 421 --psrcLine; 422 423 while (cy--) { 424 psrc = psrcLine; 425 pdst = pdstLine; 426 427 if (endmask) { 428 getandputrop(P0(psrc), xoffSrc, 0, nend, 429 P0(pdst), rop); 430 getandputrop(P1(psrc), xoffSrc, 0, nend, 431 P1(pdst), rop); 432 getandputrop(P2(psrc), xoffSrc, 0, nend, 433 P2(pdst), rop); 434 getandputrop(P3(psrc), xoffSrc, 0, nend, 435 P3(pdst), rop); 436 } 437 438 nl = nlMiddle + 1; 439 while (--nl) { 440 --psrc; 441 --pdst; 442 if (rop == RR_CLEAR) { 443 *P0(pdst) = 0; 444 *P1(pdst) = 0; 445 *P2(pdst) = 0; 446 *P3(pdst) = 0; 447 } else { 448 getunalignedword(P0(psrc), 449 xoffSrc, *P0(pdst)); 450 getunalignedword(P1(psrc), 451 xoffSrc, *P1(pdst)); 452 getunalignedword(P2(psrc), 453 xoffSrc, *P2(pdst)); 454 getunalignedword(P3(psrc), 455 xoffSrc, *P3(pdst)); 456 } 457 } 458 459 if (startmask) { 460 if (srcStartOver) 461 --psrc; 462 --pdst; 463 getandputrop(P0(psrc), (sx & 0x1f), 464 (dx & 0x1f), nstart, P0(pdst), rop); 465 getandputrop(P1(psrc), (sx & 0x1f), 466 (dx & 0x1f), nstart, P1(pdst), rop); 467 getandputrop(P2(psrc), (sx & 0x1f), 468 (dx & 0x1f), nstart, P2(pdst), rop); 469 getandputrop(P3(psrc), (sx & 0x1f), 470 (dx & 0x1f), nstart, P3(pdst), rop); 471 } 472 473 pdstLine += width; 474 psrcLine += width; 475 } 476 } 477 } 478 479 return (0); 480 } 481