| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: topcat.c,v 1.11 2024/05/01 19:28:33 tsutsui Exp $ */ | | 1 | /* $NetBSD: topcat.c,v 1.12 2024/05/04 16:06:57 tsutsui Exp $ */ |
2 | /* $OpenBSD: topcat.c,v 1.15 2006/08/11 18:33:13 miod Exp $ */ | | 2 | /* $OpenBSD: topcat.c,v 1.15 2006/08/11 18:33:13 miod Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (c) 2005, Miodrag Vallat. | | 5 | * Copyright (c) 2005, Miodrag Vallat. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -341,31 +341,44 @@ topcat_reset(struct diofb *fb, int scode | | | @@ -341,31 +341,44 @@ topcat_reset(struct diofb *fb, int scode |
341 | fb->planemask = *fbp; | | 341 | fb->planemask = *fbp; |
342 | *fbp = save; | | 342 | *fbp = save; |
343 | | | 343 | |
344 | for (fb->planes = 1; fb->planemask >= (1 << fb->planes); | | 344 | for (fb->planes = 1; fb->planemask >= (1 << fb->planes); |
345 | fb->planes++); | | 345 | fb->planes++); |
346 | if (fb->planes > 8) | | 346 | if (fb->planes > 8) |
347 | fb->planes = 8; | | 347 | fb->planes = 8; |
348 | fb->planemask = (1 << fb->planes) - 1; | | 348 | fb->planemask = (1 << fb->planes) - 1; |
349 | } | | 349 | } |
350 | | | 350 | |
351 | /* | | 351 | /* |
352 | * Some displays, such as the HP332 and HP340 internal video | | 352 | * Some displays, such as the HP332 and HP340 internal video |
353 | * and HP98542/98543 appear to return a display width of 1024 | | 353 | * and HP98542/98543 appear to return a display width of 1024 |
354 | * instead of 512. | | 354 | * instead of 512. It looks these boards have actually have |
| | | 355 | * enough 64KB (1bpp) or 256KB (4bpp) VRAM and RAMDAC capabilities |
| | | 356 | * to display 1024x400 pixels. |
355 | * | | 357 | * |
356 | * It looks these boards have VRAM with sparse address layout, | | 358 | * However HP's officlal "Service Information Manual" for |
357 | * i.e. 1 bit or 4 bits per pixel but 2 bytes per pixel, so | | 359 | * "HP 900 Series 300 Computers Models 330/350" says: |
358 | * we have to handle 512 pixels per line with 1024 bytes per line. | | 360 | * "The medium-resolution board uses eight memory chips per plane. |
| | | 361 | * This is enough to display 512 doubled pixels by 400 scan lines." |
| | | 362 | * |
| | | 363 | * This "512 doubled pixels" implies that the native HP-UX treated |
| | | 364 | * these 1024x400 framebuffers as pseudo 512x400 ones because |
| | | 365 | * ancient 1980s CRTs (such as 35741) didn't display such higher |
| | | 366 | * resolution. Furthermore, even modern LCDs can only handle |
| | | 367 | * upto 720 pixels in the "400 line" as VGA compatible mode. |
| | | 368 | * |
| | | 369 | * As mentioned above, we treat these 1024x400 1 bit or 4 bit |
| | | 370 | * framebuffers as "2 bytes per pixel" ones, so we have to handle |
| | | 371 | * 512 pixels per line with 1024 bytes per line. |
359 | */ | | 372 | */ |
360 | if (fb->planes <= 4 && fb->dwidth == 1024 && fb->dheight == 400) { | | 373 | if (fb->planes <= 4 && fb->dwidth == 1024 && fb->dheight == 400) { |
361 | fb->dwidth = 512; | | 374 | fb->dwidth = 512; |
362 | sparse = true; | | 375 | sparse = true; |
363 | } | | 376 | } |
364 | | | 377 | |
365 | fb->bmv = topcat_windowmove; | | 378 | fb->bmv = topcat_windowmove; |
366 | topcat_restore(fb); | | 379 | topcat_restore(fb); |
367 | diofb_fbsetup(fb); | | 380 | diofb_fbsetup(fb); |
368 | if (!sparse) { | | 381 | if (!sparse) { |
369 | /* save original rasops putchar op */ | | 382 | /* save original rasops putchar op */ |
370 | fb->wsputchar = ri->ri_ops.putchar; | | 383 | fb->wsputchar = ri->ri_ops.putchar; |
371 | ri->ri_ops.putchar = topcat_putchar8; | | 384 | ri->ri_ops.putchar = topcat_putchar8; |
| @@ -570,27 +583,28 @@ topcat_putchar8(void *cookie, int row, i | | | @@ -570,27 +583,28 @@ topcat_putchar8(void *cookie, int row, i |
570 | { | | 583 | { |
571 | struct rasops_info *ri = (struct rasops_info *)cookie; | | 584 | struct rasops_info *ri = (struct rasops_info *)cookie; |
572 | struct diofb *diofb = ri->ri_hw; | | 585 | struct diofb *diofb = ri->ri_hw; |
573 | volatile struct tcboxfb *tc = (struct tcboxfb *)diofb->regkva; | | 586 | volatile struct tcboxfb *tc = (struct tcboxfb *)diofb->regkva; |
574 | | | 587 | |
575 | /* Wait windowmove ops complete before drawing a glyph */ | | 588 | /* Wait windowmove ops complete before drawing a glyph */ |
576 | tc_waitbusy(tc, diofb->planemask); | | 589 | tc_waitbusy(tc, diofb->planemask); |
577 | | | 590 | |
578 | /* Call the original rasops putchar */ | | 591 | /* Call the original rasops putchar */ |
579 | (*diofb->wsputchar)(cookie, row, col, uc, attr); | | 592 | (*diofb->wsputchar)(cookie, row, col, uc, attr); |
580 | } | | 593 | } |
581 | | | 594 | |
582 | /* | | 595 | /* |
583 | * Put a single character on 1 bpp or 4 bpp variants with sparse VRAM addresses | | 596 | * Put a single character on 1 bpp (98542) or 4 bpp (98543) variants |
| | | 597 | * with 1024x400 VRAM to treat them as a pseudo 512x400 bitmap. |
584 | */ | | 598 | */ |
585 | static void | | 599 | static void |
586 | topcat_putchar1_4(void *cookie, int row, int col, u_int uc, long attr) | | 600 | topcat_putchar1_4(void *cookie, int row, int col, u_int uc, long attr) |
587 | { | | 601 | { |
588 | int width, height, cnt, fs; | | 602 | int width, height, cnt, fs; |
589 | uint32_t fb; | | 603 | uint32_t fb; |
590 | uint8_t *fr, clr[2]; | | 604 | uint8_t *fr, clr[2]; |
591 | uint8_t *dp, *rp; | | 605 | uint8_t *dp, *rp; |
592 | struct rasops_info *ri; | | 606 | struct rasops_info *ri; |
593 | struct diofb *diofb; | | 607 | struct diofb *diofb; |
594 | volatile struct tcboxfb *tc; | | 608 | volatile struct tcboxfb *tc; |
595 | | | 609 | |
596 | ri = (struct rasops_info *)cookie; | | 610 | ri = (struct rasops_info *)cookie; |
| @@ -602,28 +616,28 @@ topcat_putchar1_4(void *cookie, int row, | | | @@ -602,28 +616,28 @@ topcat_putchar1_4(void *cookie, int row, |
602 | (col * ri->ri_xscale * 2); | | 616 | (col * ri->ri_xscale * 2); |
603 | | | 617 | |
604 | height = ri->ri_font->fontheight; | | 618 | height = ri->ri_font->fontheight; |
605 | width = ri->ri_font->fontwidth; | | 619 | width = ri->ri_font->fontwidth; |
606 | clr[0] = (uint8_t)ri->ri_devcmap[(attr >> 16) & 0xf]; | | 620 | clr[0] = (uint8_t)ri->ri_devcmap[(attr >> 16) & 0xf]; |
607 | clr[1] = (uint8_t)ri->ri_devcmap[(attr >> 24) & 0xf]; | | 621 | clr[1] = (uint8_t)ri->ri_devcmap[(attr >> 24) & 0xf]; |
608 | | | 622 | |
609 | /* Wait windowmove ops complete before drawing a glyph */ | | 623 | /* Wait windowmove ops complete before drawing a glyph */ |
610 | diofb = ri->ri_hw; | | 624 | diofb = ri->ri_hw; |
611 | tc = (struct tcboxfb *)diofb->regkva; | | 625 | tc = (struct tcboxfb *)diofb->regkva; |
612 | tc_waitbusy(tc, diofb->planemask); | | 626 | tc_waitbusy(tc, diofb->planemask); |
613 | | | 627 | |
614 | /* | | 628 | /* |
615 | * At least HP98543 requires to write 4 bpp data onto | | 629 | * We have to put pixel data to both odd and even addresses |
616 | * both odd and even addresses. | | 630 | * to handle "doubled pixels" as noted above. |
617 | */ | | 631 | */ |
618 | if (uc == ' ') { | | 632 | if (uc == ' ') { |
619 | uint16_t c = clr[0]; | | 633 | uint16_t c = clr[0]; |
620 | | | 634 | |
621 | c = c << 8 | c; | | 635 | c = c << 8 | c; |
622 | while (height--) { | | 636 | while (height--) { |
623 | dp = rp; | | 637 | dp = rp; |
624 | rp += ri->ri_stride; | | 638 | rp += ri->ri_stride; |
625 | | | 639 | |
626 | for (cnt = width; cnt; cnt--) { | | 640 | for (cnt = width; cnt; cnt--) { |
627 | *(uint16_t *)dp = c; | | 641 | *(uint16_t *)dp = c; |
628 | dp += 2; | | 642 | dp += 2; |
629 | } | | 643 | } |