1 /* $OpenBSD: sti.c,v 1.72 2014/07/12 18:48:17 tedu Exp $ */ 2 3 /* 4 * Copyright (c) 2000-2003 Michael Shalayeff 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 WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES 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 MIND, 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 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 /* 29 * TODO: 30 * call sti procs asynchronously; 31 * implement console scroll-back; 32 * X11 support. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/device.h> 38 #include <sys/malloc.h> 39 40 #include <uvm/uvm_extern.h> 41 42 #include <machine/bus.h> 43 44 #include <dev/wscons/wsdisplayvar.h> 45 #include <dev/wscons/wsconsio.h> 46 47 #include <dev/ic/stireg.h> 48 #include <dev/ic/stivar.h> 49 50 #include "sti.h" 51 52 struct cfdriver sti_cd = { 53 NULL, "sti", DV_DULL 54 }; 55 56 int sti_alloc_attr(void *, int, int, int, long *); 57 int sti_copycols(void *, int, int, int, int); 58 int sti_copyrows(void *, int, int, int); 59 int sti_cursor(void *, int, int, int); 60 int sti_erasecols(void *, int, int, int, long); 61 int sti_eraserows(void *, int, int, long); 62 int sti_mapchar(void *, int, u_int *); 63 int sti_putchar(void *, int, int, u_int, long); 64 void sti_unpack_attr(void *, long, int *, int *, int *); 65 66 struct wsdisplay_emulops sti_emulops = { 67 sti_cursor, 68 sti_mapchar, 69 sti_putchar, 70 sti_copycols, 71 sti_erasecols, 72 sti_copyrows, 73 sti_eraserows, 74 sti_alloc_attr, 75 sti_unpack_attr 76 }; 77 78 int sti_alloc_screen(void *, const struct wsscreen_descr *, void **, int *, 79 int *, long *); 80 void sti_free_screen(void *, void *); 81 int sti_ioctl(void *, u_long, caddr_t, int, struct proc *); 82 paddr_t sti_mmap(void *, off_t, int); 83 int sti_show_screen(void *, void *, int, void (*)(void *, int, int), 84 void *); 85 86 const struct wsdisplay_accessops sti_accessops = { 87 .ioctl = sti_ioctl, 88 .mmap = sti_mmap, 89 .alloc_screen = sti_alloc_screen, 90 .free_screen = sti_free_screen, 91 .show_screen = sti_show_screen 92 }; 93 94 enum sti_bmove_funcs { 95 bmf_clear, bmf_copy, bmf_invert, bmf_underline 96 }; 97 98 void sti_bmove(struct sti_screen *, int, int, int, int, int, int, 99 enum sti_bmove_funcs); 100 int sti_init(struct sti_screen *, int); 101 #define STI_TEXTMODE 0x01 102 #define STI_CLEARSCR 0x02 103 int sti_inqcfg(struct sti_screen *, struct sti_inqconfout *); 104 int sti_setcment(struct sti_screen *, u_int, u_char, u_char, u_char); 105 106 struct sti_screen * 107 sti_attach_screen(struct sti_softc *, int); 108 void sti_describe_screen(struct sti_softc *, struct sti_screen *); 109 void sti_end_attach_screen(struct sti_softc *, struct sti_screen *, int); 110 int sti_fetchfonts(struct sti_screen *, struct sti_inqconfout *, u_int32_t, 111 u_int); 112 void sti_region_setup(struct sti_screen *); 113 int sti_rom_setup(struct sti_rom *, bus_space_tag_t, bus_space_tag_t, 114 bus_space_handle_t, bus_addr_t *, u_int); 115 int sti_screen_setup(struct sti_screen *, int); 116 117 #if NSTI_PCI > 0 118 #define STI_ENABLE_ROM(sc) \ 119 do { \ 120 if ((sc) != NULL && (sc)->sc_enable_rom != NULL) \ 121 (*(sc)->sc_enable_rom)(sc); \ 122 } while (0) 123 #define STI_DISABLE_ROM(sc) \ 124 do { \ 125 if ((sc) != NULL && (sc)->sc_disable_rom != NULL) \ 126 (*(sc)->sc_disable_rom)(sc); \ 127 } while (0) 128 #else 129 #define STI_ENABLE_ROM(sc) do { /* nothing */ } while (0) 130 #define STI_DISABLE_ROM(sc) do { /* nothing */ } while (0) 131 #endif 132 133 /* Macros to read larger than 8 bit values from byte roms */ 134 #define parseshort(o) \ 135 ((bus_space_read_1(memt, romh, (o) + 3) << 8) | \ 136 (bus_space_read_1(memt, romh, (o) + 7))) 137 #define parseword(o) \ 138 ((bus_space_read_1(memt, romh, (o) + 3) << 24) | \ 139 (bus_space_read_1(memt, romh, (o) + 7) << 16) | \ 140 (bus_space_read_1(memt, romh, (o) + 11) << 8) | \ 141 (bus_space_read_1(memt, romh, (o) + 15))) 142 143 int 144 sti_attach_common(struct sti_softc *sc, bus_space_tag_t iot, 145 bus_space_tag_t memt, bus_space_handle_t romh, u_int codebase) 146 { 147 struct sti_rom *rom; 148 int rc; 149 150 rom = (struct sti_rom *)malloc(sizeof(*rom), M_DEVBUF, 151 M_NOWAIT | M_ZERO); 152 if (rom == NULL) { 153 printf("cannot allocate rom data\n"); 154 return (ENOMEM); 155 } 156 157 rom->rom_softc = sc; 158 rc = sti_rom_setup(rom, iot, memt, romh, sc->bases, codebase); 159 if (rc != 0) { 160 free(rom, M_DEVBUF, 0); 161 return (rc); 162 } 163 164 sc->sc_rom = rom; 165 166 sti_describe(sc); 167 168 sc->sc_scr = sti_attach_screen(sc, 169 sc->sc_flags & STI_CONSOLE ? 0 : STI_CLEARSCR); 170 if (sc->sc_scr == NULL) 171 rc = ENOMEM; 172 173 return (rc); 174 } 175 176 struct sti_screen * 177 sti_attach_screen(struct sti_softc *sc, int flags) 178 { 179 struct sti_screen *scr; 180 int rc; 181 182 scr = (struct sti_screen *)malloc(sizeof(*scr), M_DEVBUF, 183 M_NOWAIT | M_ZERO); 184 if (scr == NULL) { 185 printf("cannot allocate screen data\n"); 186 return (NULL); 187 } 188 189 scr->scr_rom = sc->sc_rom; 190 rc = sti_screen_setup(scr, flags); 191 if (rc != 0) { 192 free(scr, M_DEVBUF, 0); 193 return (NULL); 194 } 195 196 sti_describe_screen(sc, scr); 197 198 return (scr); 199 } 200 201 int 202 sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt, 203 bus_space_handle_t romh, bus_addr_t *bases, u_int codebase) 204 { 205 struct sti_dd *dd; 206 int error, size, i; 207 208 STI_ENABLE_ROM(rom->rom_softc); 209 210 rom->iot = iot; 211 rom->memt = memt; 212 rom->romh = romh; 213 rom->bases = bases; 214 215 /* 216 * Get ROM header and code function pointers. 217 */ 218 219 dd = &rom->rom_dd; 220 rom->rom_devtype = bus_space_read_1(memt, romh, 3); 221 if (rom->rom_devtype == STI_DEVTYPE1) { 222 dd->dd_type = bus_space_read_1(memt, romh, 0x03); 223 dd->dd_nmon = bus_space_read_1(memt, romh, 0x07); 224 dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b); 225 dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f); 226 dd->dd_grid[0] = parseword(0x10); 227 dd->dd_grid[1] = parseword(0x20); 228 dd->dd_fntaddr = parseword(0x30) & ~3; 229 dd->dd_maxst = parseword(0x40); 230 dd->dd_romend = parseword(0x50) & ~3; 231 dd->dd_reglst = parseword(0x60) & ~3; 232 dd->dd_maxreent = parseshort(0x70); 233 dd->dd_maxtimo = parseshort(0x78); 234 dd->dd_montbl = parseword(0x80) & ~3; 235 dd->dd_udaddr = parseword(0x90) & ~3; 236 dd->dd_stimemreq = parseword(0xa0); 237 dd->dd_udsize = parseword(0xb0); 238 dd->dd_pwruse = parseshort(0xc0); 239 dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb); 240 dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf); 241 dd->dd_altcodet = bus_space_read_1(memt, romh, 0xd3); 242 dd->dd_eddst[0] = bus_space_read_1(memt, romh, 0xd7); 243 dd->dd_eddst[1] = bus_space_read_1(memt, romh, 0xdb); 244 dd->dd_eddst[2] = bus_space_read_1(memt, romh, 0xdf); 245 dd->dd_cfbaddr = parseword(0xe0) & ~3; 246 247 codebase <<= 2; 248 dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3; 249 dd->dd_pacode[0x1] = parseword(codebase + 0x010) & ~3; 250 dd->dd_pacode[0x2] = parseword(codebase + 0x020) & ~3; 251 dd->dd_pacode[0x3] = parseword(codebase + 0x030) & ~3; 252 dd->dd_pacode[0x4] = parseword(codebase + 0x040) & ~3; 253 dd->dd_pacode[0x5] = parseword(codebase + 0x050) & ~3; 254 dd->dd_pacode[0x6] = parseword(codebase + 0x060) & ~3; 255 dd->dd_pacode[0x7] = parseword(codebase + 0x070) & ~3; 256 dd->dd_pacode[0x8] = parseword(codebase + 0x080) & ~3; 257 dd->dd_pacode[0x9] = parseword(codebase + 0x090) & ~3; 258 dd->dd_pacode[0xa] = parseword(codebase + 0x0a0) & ~3; 259 dd->dd_pacode[0xb] = parseword(codebase + 0x0b0) & ~3; 260 dd->dd_pacode[0xc] = parseword(codebase + 0x0c0) & ~3; 261 dd->dd_pacode[0xd] = parseword(codebase + 0x0d0) & ~3; 262 dd->dd_pacode[0xe] = parseword(codebase + 0x0e0) & ~3; 263 dd->dd_pacode[0xf] = parseword(codebase + 0x0f0) & ~3; 264 } else { /* STI_DEVTYPE4 */ 265 bus_space_read_raw_region_4(memt, romh, 0, (u_int8_t *)dd, 266 sizeof(*dd)); 267 /* fix pacode... */ 268 bus_space_read_raw_region_4(memt, romh, codebase, 269 (u_int8_t *)dd->dd_pacode, sizeof(dd->dd_pacode)); 270 } 271 272 STI_DISABLE_ROM(rom->rom_softc); 273 274 #ifdef STIDEBUG 275 printf("dd:\n" 276 "devtype=%x, rev=%x;%d, altt=%x, gid=%08x%08x, font=%x, mss=%x\n" 277 "end=%x, regions=%x, msto=%x, timo=%d, mont=%x, user=%x[%x]\n" 278 "memrq=%x, pwr=%d, bus=%x, ebus=%x, cfb=%x\n" 279 "code=", 280 dd->dd_type & 0xff, dd->dd_grrev, dd->dd_lrrev, dd->dd_altcodet, 281 dd->dd_grid[0], dd->dd_grid[1], dd->dd_fntaddr, dd->dd_maxst, 282 dd->dd_romend, dd->dd_reglst, dd->dd_maxreent, dd->dd_maxtimo, 283 dd->dd_montbl, dd->dd_udaddr, dd->dd_udsize, dd->dd_stimemreq, 284 dd->dd_pwruse, dd->dd_bussup, dd->dd_ebussup, dd->dd_cfbaddr); 285 printf("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", 286 dd->dd_pacode[0x0], dd->dd_pacode[0x1], dd->dd_pacode[0x2], 287 dd->dd_pacode[0x3], dd->dd_pacode[0x4], dd->dd_pacode[0x5], 288 dd->dd_pacode[0x6], dd->dd_pacode[0x7], dd->dd_pacode[0x8], 289 dd->dd_pacode[0x9], dd->dd_pacode[0xa], dd->dd_pacode[0xb], 290 dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe], 291 dd->dd_pacode[0xf]); 292 #endif 293 294 /* 295 * Figure out how much bytes we need for the STI code. 296 * Note there could be fewer than STI_END entries pointer 297 * entries populated, especially on older devices. 298 */ 299 300 for (i = STI_END; !dd->dd_pacode[i]; i--) 301 ; 302 size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN]; 303 if (rom->rom_devtype == STI_DEVTYPE1) 304 size = (size + 3) / 4; 305 if (size == 0) { 306 printf(": no code for the requested platform\n"); 307 return (EINVAL); 308 } 309 310 if (!(rom->rom_code = uvm_km_alloc(kernel_map, round_page(size)))) { 311 printf(": cannot allocate %u bytes for code\n", size); 312 return (ENOMEM); 313 } 314 #ifdef STIDEBUG 315 printf("code=0x%x[%x]\n", rom->rom_code, size); 316 #endif 317 318 /* 319 * Copy code into memory and make it executable. 320 */ 321 322 STI_ENABLE_ROM(rom->rom_softc); 323 324 if (rom->rom_devtype == STI_DEVTYPE1) { 325 u_int8_t *p = (u_int8_t *)rom->rom_code; 326 u_int32_t addr, eaddr; 327 328 for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4; 329 addr < eaddr; addr += 4 ) 330 *p++ = bus_space_read_4(memt, romh, addr) & 0xff; 331 332 } else /* STI_DEVTYPE4 */ 333 bus_space_read_raw_region_4(memt, romh, 334 dd->dd_pacode[STI_BEGIN], (u_int8_t *)rom->rom_code, 335 size); 336 337 STI_DISABLE_ROM(rom->rom_softc); 338 339 if ((error = uvm_map_protect(kernel_map, rom->rom_code, 340 rom->rom_code + round_page(size), UVM_PROT_RX, FALSE))) { 341 printf(": uvm_map_protect failed (%d)\n", error); 342 uvm_km_free(kernel_map, rom->rom_code, round_page(size)); 343 return (error); 344 } 345 346 /* 347 * Setup code function pointers. 348 */ 349 350 #define O(i) \ 351 (dd->dd_pacode[(i)] == 0 ? 0 : \ 352 (rom->rom_code + (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \ 353 (rom->rom_devtype == STI_DEVTYPE1? 4 : 1))) 354 355 rom->init = (sti_init_t) O(STI_INIT_GRAPH); 356 rom->mgmt = (sti_mgmt_t) O(STI_STATE_MGMT); 357 rom->unpmv = (sti_unpmv_t) O(STI_FONT_UNPMV); 358 rom->blkmv = (sti_blkmv_t) O(STI_BLOCK_MOVE); 359 rom->test = (sti_test_t) O(STI_SELF_TEST); 360 rom->exhdl = (sti_exhdl_t) O(STI_EXCEP_HDLR); 361 rom->inqconf = (sti_inqconf_t)O(STI_INQ_CONF); 362 rom->scment = (sti_scment_t)O(STI_SCM_ENT); 363 rom->dmac = (sti_dmac_t) O(STI_DMA_CTRL); 364 rom->flowc = (sti_flowc_t) O(STI_FLOW_CTRL); 365 rom->utiming = (sti_utiming_t)O(STI_UTIMING); 366 rom->pmgr = (sti_pmgr_t) O(STI_PROC_MGR); 367 rom->util = (sti_util_t) O(STI_UTIL); 368 369 #undef O 370 371 /* 372 * Set colormap entry is not implemented until 8.04, so force 373 * a NULL pointer here. 374 */ 375 if (dd->dd_grrev < STI_REVISION(8,4)) { 376 rom->scment = NULL; 377 } 378 379 return (0); 380 } 381 382 /* 383 * Map all regions. 384 */ 385 void 386 sti_region_setup(struct sti_screen *scr) 387 { 388 struct sti_rom *rom = scr->scr_rom; 389 bus_space_tag_t memt = rom->memt; 390 bus_space_handle_t romh = rom->romh; 391 bus_addr_t *bases = rom->bases; 392 struct sti_dd *dd = &rom->rom_dd; 393 struct sti_cfg *cc = &scr->scr_cfg; 394 bus_space_handle_t bh; 395 struct sti_region regions[STI_REGION_MAX], *r; 396 u_int regno, regcnt; 397 bus_addr_t addr; 398 399 #ifdef STIDEBUG 400 printf("stiregions @%p:\n", dd->dd_reglst); 401 #endif 402 403 /* 404 * Read the region information. 405 */ 406 407 STI_ENABLE_ROM(rom->rom_softc); 408 409 if (rom->rom_devtype == STI_DEVTYPE1) { 410 for (regno = 0; regno < STI_REGION_MAX; regno++) 411 *(u_int *)(regions + regno) = 412 parseword(dd->dd_reglst + regno * 0x10); 413 } else { 414 bus_space_read_raw_region_4(memt, romh, dd->dd_reglst, 415 (u_int8_t *)regions, sizeof regions); 416 } 417 418 STI_DISABLE_ROM(rom->rom_softc); 419 420 /* 421 * Count them. 422 */ 423 424 for (regcnt = 0, r = regions; regcnt < STI_REGION_MAX; regcnt++, r++) 425 if (r->last) 426 break; 427 regcnt++; 428 429 /* 430 * Map them. 431 */ 432 433 for (regno = 0, r = regions; regno < regcnt; regno++, r++) { 434 if (r->length == 0) 435 continue; 436 437 /* 438 * Assume an existing mapping exists. 439 */ 440 addr = bases[regno] + (r->offset << PGSHIFT); 441 442 #ifdef STIDEBUG 443 printf("%08x @ 0x%08x%s%s%s%s\n", 444 r->length << PGSHIFT, addr, r->sys_only ? " sys" : "", 445 r->cache ? " cache" : "", r->btlb ? " btlb" : "", 446 r->last ? " last" : ""); 447 #endif 448 449 /* 450 * Region #0 is always the rom, and it should have been 451 * mapped already. 452 * XXX This expects a 1:1 mapping... 453 */ 454 if (regno == 0 && romh == bases[0]) { 455 cc->regions[0] = addr; 456 continue; 457 } 458 459 if (bus_space_map(memt, addr, r->length << PGSHIFT, 460 r->cache ? BUS_SPACE_MAP_CACHEABLE : 0, &bh)) { 461 #ifdef STIDEBUG 462 printf("already mapped region\n"); 463 #endif 464 } else { 465 /* XXX should use bus_space_vaddr */ 466 addr = (bus_addr_t)bh; 467 if (regno == 1) { 468 scr->fbaddr = addr; 469 scr->fblen = r->length << PGSHIFT; 470 } 471 } 472 473 cc->regions[regno] = addr; 474 } 475 476 #ifdef STIDEBUG 477 /* 478 * Make sure we'll trap accessing unmapped regions 479 */ 480 for (regno = 0; regno < STI_REGION_MAX; regno++) 481 if (cc->regions[regno] == 0) 482 cc->regions[regno] = 0x81234567; 483 #endif 484 } 485 486 int 487 sti_screen_setup(struct sti_screen *scr, int flags) 488 { 489 struct sti_rom *rom = scr->scr_rom; 490 bus_space_tag_t memt = rom->memt; 491 bus_space_handle_t romh = rom->romh; 492 struct sti_dd *dd = &rom->rom_dd; 493 struct sti_cfg *cc = &scr->scr_cfg; 494 struct sti_inqconfout cfg; 495 struct sti_einqconfout ecfg; 496 int error, i; 497 int geometry_kluge = 0; 498 u_int fontindex = 0; 499 500 bzero(cc, sizeof (*cc)); 501 cc->ext_cfg = &scr->scr_ecfg; 502 bzero(cc->ext_cfg, sizeof(*cc->ext_cfg)); 503 504 if (dd->dd_stimemreq) { 505 scr->scr_ecfg.addr = 506 malloc(dd->dd_stimemreq, M_DEVBUF, M_NOWAIT); 507 if (!scr->scr_ecfg.addr) { 508 printf("cannot allocate %d bytes for STI\n", 509 dd->dd_stimemreq); 510 return (ENOMEM); 511 } 512 } 513 514 sti_region_setup(scr); 515 516 if ((error = sti_init(scr, 0))) { 517 printf(": can not initialize (%d)\n", error); 518 goto fail; 519 } 520 521 bzero(&cfg, sizeof(cfg)); 522 bzero(&ecfg, sizeof(ecfg)); 523 cfg.ext = &ecfg; 524 if ((error = sti_inqcfg(scr, &cfg))) { 525 printf(": error %d inquiring config\n", error); 526 goto fail; 527 } 528 529 /* 530 * Older (rev 8.02) boards report wrong offset values, 531 * similar to the displayable area size, at least in m68k mode. 532 * Attempt to detect this and adjust here. 533 */ 534 if (cfg.owidth == cfg.width && 535 cfg.oheight == cfg.height) 536 geometry_kluge = 1; 537 538 if (geometry_kluge) { 539 scr->scr_cfg.oscr_width = cfg.owidth = 540 cfg.fbwidth - cfg.width; 541 scr->scr_cfg.oscr_height = cfg.oheight = 542 cfg.fbheight - cfg.height; 543 } 544 545 /* 546 * Save a few fields for sti_describe_screen() later 547 */ 548 scr->fbheight = cfg.fbheight; 549 scr->fbwidth = cfg.fbwidth; 550 scr->oheight = cfg.oheight; 551 scr->owidth = cfg.owidth; 552 bcopy(cfg.name, scr->name, sizeof(scr->name)); 553 554 if ((error = sti_init(scr, STI_TEXTMODE | flags))) { 555 printf(": can not initialize (%d)\n", error); 556 goto fail; 557 } 558 #ifdef STIDEBUG 559 printf("conf: bpp=%d planes=%d attr=%b\n" 560 "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp, 561 cfg.planes, cfg.attributes, STI_INQCONF_BITS, 562 ecfg.crt_config[0], ecfg.crt_config[1], ecfg.crt_config[2], 563 ecfg.crt_hw[0], ecfg.crt_hw[1], ecfg.crt_hw[2]); 564 #endif 565 scr->scr_bpp = cfg.bppu; 566 567 /* 568 * Although scr->scr_ecfg.current_monitor is not filled by 569 * sti_init() as expected, we can nevertheless walk the monitor 570 * list, if there is any, and if we find a mode matching our 571 * resolution, pick its font index. 572 */ 573 if (dd->dd_montbl != 0) { 574 STI_ENABLE_ROM(rom->rom_softc); 575 576 for (i = 0; i < dd->dd_nmon; i++) { 577 u_int offs = dd->dd_montbl + 8 * i; 578 u_int32_t m[2]; 579 sti_mon_t mon = (void *)m; 580 if (rom->rom_devtype == STI_DEVTYPE1) { 581 m[0] = parseword(4 * offs); 582 m[1] = parseword(4 * (offs + 4)); 583 } else { 584 bus_space_read_raw_region_4(memt, romh, offs, 585 (u_int8_t *)mon, sizeof(*mon)); 586 } 587 588 if (mon->width == scr->scr_cfg.scr_width && 589 mon->height == scr->scr_cfg.scr_height) { 590 fontindex = mon->font; 591 break; 592 } 593 } 594 595 STI_DISABLE_ROM(rom->rom_softc); 596 597 #ifdef STIDEBUG 598 printf("font index: %d\n", fontindex); 599 #endif 600 } 601 602 if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr, fontindex))) { 603 printf(": cannot fetch fonts (%d)\n", error); 604 goto fail; 605 } 606 607 /* 608 * setup screen descriptions: 609 * figure number of fonts supported; 610 * allocate wscons structures; 611 * calculate dimensions. 612 */ 613 614 strlcpy(scr->scr_wsd.name, "std", sizeof(scr->scr_wsd.name)); 615 scr->scr_wsd.ncols = cfg.width / scr->scr_curfont.width; 616 scr->scr_wsd.nrows = cfg.height / scr->scr_curfont.height; 617 scr->scr_wsd.textops = &sti_emulops; 618 scr->scr_wsd.fontwidth = scr->scr_curfont.width; 619 scr->scr_wsd.fontheight = scr->scr_curfont.height; 620 scr->scr_wsd.capabilities = WSSCREEN_REVERSE; 621 622 scr->scr_scrlist[0] = &scr->scr_wsd; 623 scr->scr_screenlist.nscreens = 1; 624 scr->scr_screenlist.screens = 625 (const struct wsscreen_descr **)scr->scr_scrlist; 626 627 return (0); 628 629 fail: 630 /* XXX free resources */ 631 if (scr->scr_ecfg.addr != NULL) { 632 free(scr->scr_ecfg.addr, M_DEVBUF, 0); 633 scr->scr_ecfg.addr = NULL; 634 } 635 636 return (ENXIO); 637 } 638 639 void 640 sti_describe_screen(struct sti_softc *sc, struct sti_screen *scr) 641 { 642 struct sti_font *fp = &scr->scr_curfont; 643 644 printf("%s: %s, %dx%d frame buffer, %dx%dx%d display\n", 645 sc->sc_dev.dv_xname, scr->name, scr->fbwidth, scr->fbheight, 646 scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp); 647 648 printf("%s: %dx%d font type %d, %d bpc, charset %d-%d\n", 649 sc->sc_dev.dv_xname, fp->width, fp->height, 650 fp->type, fp->bpc, fp->first, fp->last); 651 } 652 653 void 654 sti_describe(struct sti_softc *sc) 655 { 656 struct sti_rom *rom = sc->sc_rom; 657 struct sti_dd *dd = &rom->rom_dd; 658 659 printf(": rev %d.%02d;%d, ID 0x%08X%08X\n", 660 dd->dd_grrev >> 4, dd->dd_grrev & 0xf, 661 dd->dd_lrrev, dd->dd_grid[0], dd->dd_grid[1]); 662 663 if (sc->sc_scr != NULL) 664 sti_describe_screen(sc, sc->sc_scr); 665 } 666 667 /* 668 * Final part of attachment. On hppa where we use the PDC console 669 * during autoconf, this has to be postponed until autoconf has 670 * completed. 671 */ 672 void 673 sti_end_attach(void *v) 674 { 675 struct sti_softc *sc = (struct sti_softc *)v; 676 677 if (sc->sc_scr != NULL) 678 sti_end_attach_screen(sc, sc->sc_scr, 679 sc->sc_flags & STI_CONSOLE ? 1 : 0); 680 } 681 682 void 683 sti_end_attach_screen(struct sti_softc *sc, struct sti_screen *scr, int console) 684 { 685 struct wsemuldisplaydev_attach_args waa; 686 687 scr->scr_wsmode = WSDISPLAYIO_MODE_EMUL; 688 689 waa.console = console; 690 waa.scrdata = &scr->scr_screenlist; 691 waa.accessops = &sti_accessops; 692 waa.accesscookie = scr; 693 waa.defaultscreens = 0; 694 695 /* attach as console if required */ 696 if (console && !ISSET(sc->sc_flags, STI_ATTACHED)) { 697 long defattr; 698 699 sti_alloc_attr(scr, 0, 0, 0, &defattr); 700 wsdisplay_cnattach(&scr->scr_wsd, scr, 701 0, scr->scr_wsd.nrows - 1, defattr); 702 sc->sc_flags |= STI_ATTACHED; 703 } 704 705 config_found(&sc->sc_dev, &waa, wsemuldisplaydevprint); 706 } 707 708 u_int 709 sti_rom_size(bus_space_tag_t memt, bus_space_handle_t romh) 710 { 711 int devtype; 712 u_int romend; 713 714 devtype = bus_space_read_1(memt, romh, 3); 715 if (devtype == STI_DEVTYPE4) { 716 bus_space_read_raw_region_4(memt, romh, 0x18, 717 (u_int8_t *)&romend, 4); 718 } else { 719 romend = parseword(0x50); 720 } 721 722 return (round_page(romend)); 723 } 724 725 int 726 sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, 727 u_int32_t baseaddr, u_int fontindex) 728 { 729 struct sti_rom *rom = scr->scr_rom; 730 bus_space_tag_t memt = rom->memt; 731 bus_space_handle_t romh = rom->romh; 732 struct sti_font *fp = &scr->scr_curfont; 733 u_int32_t addr; 734 int size; 735 #ifdef notyet 736 int uc; 737 struct { 738 struct sti_unpmvflags flags; 739 struct sti_unpmvin in; 740 struct sti_unpmvout out; 741 } a; 742 #endif 743 744 /* 745 * Get the first PROM font in memory 746 */ 747 748 STI_ENABLE_ROM(rom->rom_softc); 749 750 rescan: 751 addr = baseaddr; 752 do { 753 if (rom->rom_devtype == STI_DEVTYPE1) { 754 fp->first = parseshort(addr + 0x00); 755 fp->last = parseshort(addr + 0x08); 756 fp->width = bus_space_read_1(memt, romh, 757 addr + 0x13); 758 fp->height = bus_space_read_1(memt, romh, 759 addr + 0x17); 760 fp->type = bus_space_read_1(memt, romh, 761 addr + 0x1b); 762 fp->bpc = bus_space_read_1(memt, romh, 763 addr + 0x1f); 764 fp->next = parseword(addr + 0x20); 765 fp->uheight= bus_space_read_1(memt, romh, 766 addr + 0x33); 767 fp->uoffset= bus_space_read_1(memt, romh, 768 addr + 0x37); 769 } else { /* STI_DEVTYPE4 */ 770 bus_space_read_raw_region_4(memt, romh, addr, 771 (u_int8_t *)fp, sizeof(struct sti_font)); 772 } 773 774 #ifdef STIDEBUG 775 STI_DISABLE_ROM(rom->rom_softc); 776 printf("font@%p: %d-%d, %dx%d, type %d, next %x\n", 777 addr, fp->first, fp->last, fp->width, fp->height, fp->type, 778 fp->next); 779 STI_ENABLE_ROM(rom->rom_softc); 780 #endif 781 782 if (fontindex == 0) { 783 size = sizeof(struct sti_font) + 784 (fp->last - fp->first + 1) * fp->bpc; 785 if (rom->rom_devtype == STI_DEVTYPE1) 786 size *= 4; 787 scr->scr_romfont = malloc(size, M_DEVBUF, M_NOWAIT); 788 if (scr->scr_romfont == NULL) 789 return (ENOMEM); 790 791 bus_space_read_raw_region_4(memt, romh, addr, 792 (u_int8_t *)scr->scr_romfont, size); 793 794 break; 795 } 796 797 addr = baseaddr + fp->next; 798 fontindex--; 799 } while (fp->next != 0); 800 801 /* 802 * If our font index was bogus, we did not find the expected font. 803 * In this case, pick the first one and be done with it. 804 */ 805 if (fp->next == 0 && scr->scr_romfont == NULL) { 806 fontindex = 0; 807 goto rescan; 808 } 809 810 STI_DISABLE_ROM(rom->rom_softc); 811 812 #ifdef notyet 813 /* 814 * If there is enough room in the off-screen framebuffer memory, 815 * display all the characters there in order to display them 816 * faster with blkmv operations rather than unpmv later on. 817 */ 818 if (size <= cfg->fbheight * 819 (cfg->fbwidth - cfg->width - cfg->owidth)) { 820 bzero(&a, sizeof(a)); 821 a.flags.flags = STI_UNPMVF_WAIT; 822 a.in.fg_colour = STI_COLOUR_WHITE; 823 a.in.bg_colour = STI_COLOUR_BLACK; 824 a.in.font_addr = scr->scr_romfont; 825 826 scr->scr_fontmaxcol = cfg->fbheight / fp->height; 827 scr->scr_fontbase = cfg->width + cfg->owidth; 828 for (uc = fp->first; uc <= fp->last; uc++) { 829 a.in.x = ((uc - fp->first) / scr->scr_fontmaxcol) * 830 fp->width + scr->scr_fontbase; 831 a.in.y = ((uc - fp->first) % scr->scr_fontmaxcol) * 832 fp->height; 833 a.in.index = uc; 834 835 (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 836 if (a.out.errno) { 837 #ifdef STIDEBUG 838 printf("sti_unpmv %d returned %d\n", 839 uc, a.out.errno); 840 #endif 841 return (0); 842 } 843 } 844 845 free(scr->scr_romfont, M_DEVBUF, 0); 846 scr->scr_romfont = NULL; 847 } 848 #endif 849 850 return (0); 851 } 852 853 /* 854 * Wrappers around STI code pointers 855 */ 856 857 int 858 sti_init(struct sti_screen *scr, int mode) 859 { 860 struct sti_rom *rom = scr->scr_rom; 861 struct { 862 struct sti_initflags flags; 863 struct sti_initin in; 864 struct sti_einitin ein; 865 struct sti_initout out; 866 } a; 867 868 bzero(&a, sizeof(a)); 869 870 a.flags.flags = STI_INITF_WAIT | STI_INITF_CMB | STI_INITF_EBET | 871 (mode & STI_TEXTMODE ? STI_INITF_TEXT | STI_INITF_PBET | 872 STI_INITF_PBETI | STI_INITF_ICMT : 0) | 873 (mode & STI_CLEARSCR ? STI_INITF_CLEAR : 0); 874 a.in.text_planes = 1; 875 a.in.ext_in = &a.ein; 876 #ifdef STIDEBUG 877 printf("sti_init,%p(%x, %p, %p, %p)\n", 878 rom->init, a.flags.flags, &a.in, &a.out, &scr->scr_cfg); 879 #endif 880 (*rom->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 881 if (a.out.text_planes != a.in.text_planes) 882 return (-1); /* not colliding with sti errno values */ 883 return (a.out.errno); 884 } 885 886 int 887 sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out) 888 { 889 struct sti_rom *rom = scr->scr_rom; 890 struct { 891 struct sti_inqconfflags flags; 892 struct sti_inqconfin in; 893 } a; 894 895 bzero(&a, sizeof(a)); 896 897 a.flags.flags = STI_INQCONFF_WAIT; 898 (*rom->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg); 899 900 return out->errno; 901 } 902 903 void 904 sti_bmove(struct sti_screen *scr, int x1, int y1, int x2, int y2, int h, int w, 905 enum sti_bmove_funcs f) 906 { 907 struct sti_rom *rom = scr->scr_rom; 908 struct { 909 struct sti_blkmvflags flags; 910 struct sti_blkmvin in; 911 struct sti_blkmvout out; 912 } a; 913 914 bzero(&a, sizeof(a)); 915 916 a.flags.flags = STI_BLKMVF_WAIT; 917 switch (f) { 918 case bmf_clear: 919 a.flags.flags |= STI_BLKMVF_CLR; 920 a.in.bg_colour = STI_COLOUR_BLACK; 921 break; 922 case bmf_underline: 923 case bmf_copy: 924 a.in.fg_colour = STI_COLOUR_WHITE; 925 a.in.bg_colour = STI_COLOUR_BLACK; 926 break; 927 case bmf_invert: 928 a.flags.flags |= STI_BLKMVF_COLR; 929 a.in.fg_colour = STI_COLOUR_BLACK; 930 a.in.bg_colour = STI_COLOUR_WHITE; 931 break; 932 } 933 a.in.srcx = x1; 934 a.in.srcy = y1; 935 a.in.dstx = x2; 936 a.in.dsty = y2; 937 a.in.height = h; 938 a.in.width = w; 939 940 (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 941 #ifdef STIDEBUG 942 if (a.out.errno) 943 printf("sti_blkmv returned %d\n", a.out.errno); 944 #endif 945 } 946 947 int 948 sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b) 949 { 950 struct sti_rom *rom = scr->scr_rom; 951 struct { 952 struct sti_scmentflags flags; 953 struct sti_scmentin in; 954 struct sti_scmentout out; 955 } a; 956 957 bzero(&a, sizeof(a)); 958 959 a.flags.flags = STI_SCMENTF_WAIT; 960 a.in.entry = i; 961 a.in.value = (r << 16) | (g << 8) | b; 962 963 (*rom->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 964 965 return a.out.errno; 966 } 967 968 /* 969 * wsdisplay accessops 970 */ 971 972 int 973 sti_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) 974 { 975 struct sti_screen *scr = (struct sti_screen *)v; 976 struct sti_rom *rom = scr->scr_rom; 977 struct wsdisplay_fbinfo *wdf; 978 struct wsdisplay_cmap *cmapp; 979 u_int mode, idx, count; 980 int i, ret; 981 982 ret = 0; 983 switch (cmd) { 984 case WSDISPLAYIO_SMODE: 985 mode = *(u_int *)data; 986 if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL && 987 mode == WSDISPLAYIO_MODE_DUMBFB) 988 ret = sti_init(scr, 0); 989 else if (scr->scr_wsmode == WSDISPLAYIO_MODE_DUMBFB && 990 mode == WSDISPLAYIO_MODE_EMUL) 991 ret = sti_init(scr, STI_TEXTMODE); 992 scr->scr_wsmode = mode; 993 break; 994 995 case WSDISPLAYIO_GTYPE: 996 *(u_int *)data = WSDISPLAY_TYPE_STI; 997 break; 998 999 case WSDISPLAYIO_GINFO: 1000 wdf = (struct wsdisplay_fbinfo *)data; 1001 wdf->height = scr->scr_cfg.scr_height; 1002 wdf->width = scr->scr_cfg.scr_width; 1003 wdf->depth = scr->scr_bpp; 1004 if (rom->scment == NULL) 1005 wdf->cmsize = 0; 1006 else 1007 wdf->cmsize = STI_NCMAP; 1008 break; 1009 1010 case WSDISPLAYIO_LINEBYTES: 1011 *(u_int *)data = scr->scr_cfg.fb_width; 1012 break; 1013 1014 case WSDISPLAYIO_GETCMAP: 1015 if (rom->scment == NULL) 1016 return ENODEV; 1017 cmapp = (struct wsdisplay_cmap *)data; 1018 idx = cmapp->index; 1019 count = cmapp->count; 1020 if (idx >= STI_NCMAP || idx + count > STI_NCMAP) 1021 return EINVAL; 1022 if ((ret = copyout(&scr->scr_rcmap[idx], cmapp->red, count))) 1023 break; 1024 if ((ret = copyout(&scr->scr_gcmap[idx], cmapp->green, count))) 1025 break; 1026 if ((ret = copyout(&scr->scr_bcmap[idx], cmapp->blue, count))) 1027 break; 1028 break; 1029 1030 case WSDISPLAYIO_PUTCMAP: 1031 if (rom->scment == NULL) 1032 return ENODEV; 1033 cmapp = (struct wsdisplay_cmap *)data; 1034 idx = cmapp->index; 1035 count = cmapp->count; 1036 if (idx >= STI_NCMAP || idx + count > STI_NCMAP) 1037 return EINVAL; 1038 if ((ret = copyin(cmapp->red, &scr->scr_rcmap[idx], count))) 1039 break; 1040 if ((ret = copyin(cmapp->green, &scr->scr_gcmap[idx], count))) 1041 break; 1042 if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count))) 1043 break; 1044 for (i = idx + count - 1; i >= idx; i--) 1045 if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i], 1046 scr->scr_gcmap[i], scr->scr_bcmap[i]))) { 1047 #ifdef STIDEBUG 1048 printf("sti_ioctl: " 1049 "sti_setcment(%d, %u, %u, %u): %d\n", i, 1050 (u_int)scr->scr_rcmap[i], 1051 (u_int)scr->scr_gcmap[i], 1052 (u_int)scr->scr_bcmap[i], ret); 1053 #endif 1054 ret = EINVAL; 1055 break; 1056 } 1057 break; 1058 1059 case WSDISPLAYIO_SVIDEO: 1060 case WSDISPLAYIO_GVIDEO: 1061 break; 1062 1063 default: 1064 return (-1); /* not supported yet */ 1065 } 1066 1067 return (ret); 1068 } 1069 1070 paddr_t 1071 sti_mmap(void *v, off_t offset, int prot) 1072 { 1073 #if 0 1074 struct sti_screen *scr = (struct sti_screen *)v; 1075 #endif 1076 1077 /* XXX not finished */ 1078 return -1; 1079 } 1080 1081 int 1082 sti_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, 1083 int *cxp, int *cyp, long *defattr) 1084 { 1085 struct sti_screen *scr = (struct sti_screen *)v; 1086 1087 if (scr->scr_nscreens > 0) 1088 return ENOMEM; 1089 1090 *cookiep = scr; 1091 *cxp = 0; 1092 *cyp = 0; 1093 sti_alloc_attr(scr, 0, 0, 0, defattr); 1094 scr->scr_nscreens++; 1095 return 0; 1096 } 1097 1098 void 1099 sti_free_screen(void *v, void *cookie) 1100 { 1101 struct sti_screen *scr = (struct sti_screen *)v; 1102 1103 scr->scr_nscreens--; 1104 } 1105 1106 int 1107 sti_show_screen(void *v, void *cookie, int waitok, 1108 void (*cb)(void *, int, int), void *cbarg) 1109 { 1110 #if 0 1111 struct sti_screen *scr = (struct sti_screen *)v; 1112 #endif 1113 1114 return 0; 1115 } 1116 1117 /* 1118 * wsdisplay emulops 1119 */ 1120 1121 int 1122 sti_cursor(void *v, int on, int row, int col) 1123 { 1124 struct sti_screen *scr = (struct sti_screen *)v; 1125 struct sti_font *fp = &scr->scr_curfont; 1126 1127 sti_bmove(scr, 1128 col * fp->width, row * fp->height, 1129 col * fp->width, row * fp->height, 1130 fp->height, fp->width, bmf_invert); 1131 1132 return 0; 1133 } 1134 1135 /* 1136 * ISO 8859-1 part of Unicode to HP Roman font index conversion array. 1137 */ 1138 static const u_int8_t 1139 sti_unitoroman[0x100 - 0xa0] = { 1140 0xa0, 0xb8, 0xbf, 0xbb, 0xba, 0xbc, 0, 0xbd, 1141 0xab, 0, 0xf9, 0xfb, 0, 0xf6, 0, 0xb0, 1142 1143 0xb3, 0xfe, 0, 0, 0xa8, 0xf3, 0xf4, 0xf2, 1144 0, 0, 0xfa, 0xfd, 0xf7, 0xf8, 0, 0xb9, 1145 1146 0xa1, 0xe0, 0xa2, 0xe1, 0xd8, 0xd0, 0xd3, 0xb4, 1147 0xa3, 0xdc, 0xa4, 0xa5, 0xe6, 0xe5, 0xa6, 0xa7, 1148 1149 0xe3, 0xb6, 0xe8, 0xe7, 0xdf, 0xe9, 0xda, 0, 1150 0xd2, 0xad, 0xed, 0xae, 0xdb, 0xb1, 0xf0, 0xde, 1151 1152 0xc8, 0xc4, 0xc0, 0xe2, 0xcc, 0xd4, 0xd7, 0xb5, 1153 0xc9, 0xc5, 0xc1, 0xcd, 0xd9, 0xd5, 0xd1, 0xdd, 1154 1155 0xe4, 0xb7, 0xca, 0xc6, 0xc2, 0xea, 0xce, 0, 1156 0xd6, 0xcb, 0xc7, 0xc3, 0xcf, 0xb2, 0xf1, 0xef 1157 }; 1158 1159 int 1160 sti_mapchar(void *v, int uni, u_int *index) 1161 { 1162 struct sti_screen *scr = (struct sti_screen *)v; 1163 struct sti_font *fp = &scr->scr_curfont; 1164 int c; 1165 1166 switch (fp->type) { 1167 case STI_FONT_HPROMAN8: 1168 if (uni >= 0x80 && uni < 0xa0) 1169 c = -1; 1170 else if (uni >= 0xa0 && uni < 0x100) { 1171 c = (int)sti_unitoroman[uni - 0xa0]; 1172 if (c == 0) 1173 c = -1; 1174 } else 1175 c = uni; 1176 break; 1177 default: 1178 c = uni; 1179 break; 1180 } 1181 1182 if (c == -1 || c < fp->first || c > fp->last) { 1183 *index = '?'; 1184 return (0); 1185 } 1186 1187 *index = c; 1188 return (5); 1189 } 1190 1191 int 1192 sti_putchar(void *v, int row, int col, u_int uc, long attr) 1193 { 1194 struct sti_screen *scr = (struct sti_screen *)v; 1195 struct sti_rom *rom = scr->scr_rom; 1196 struct sti_font *fp = &scr->scr_curfont; 1197 int bg, fg; 1198 1199 sti_unpack_attr(scr, attr, &fg, &bg, NULL); 1200 1201 if (scr->scr_romfont != NULL) { 1202 /* 1203 * Font is in memory, use unpmv 1204 */ 1205 struct { 1206 struct sti_unpmvflags flags; 1207 struct sti_unpmvin in; 1208 struct sti_unpmvout out; 1209 } a; 1210 1211 bzero(&a, sizeof(a)); 1212 1213 a.flags.flags = STI_UNPMVF_WAIT; 1214 a.in.fg_colour = fg; 1215 a.in.bg_colour = bg; 1216 1217 a.in.x = col * fp->width; 1218 a.in.y = row * fp->height; 1219 a.in.font_addr = scr->scr_romfont; 1220 a.in.index = uc; 1221 1222 (*rom->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 1223 } else { 1224 /* 1225 * Font is in frame buffer, use blkmv 1226 */ 1227 struct { 1228 struct sti_blkmvflags flags; 1229 struct sti_blkmvin in; 1230 struct sti_blkmvout out; 1231 } a; 1232 1233 bzero(&a, sizeof(a)); 1234 1235 a.flags.flags = STI_BLKMVF_WAIT; 1236 a.in.fg_colour = fg; 1237 a.in.bg_colour = bg; 1238 1239 a.in.srcx = ((uc - fp->first) / scr->scr_fontmaxcol) * 1240 fp->width + scr->scr_fontbase; 1241 a.in.srcy = ((uc - fp->first) % scr->scr_fontmaxcol) * 1242 fp->height; 1243 a.in.dstx = col * fp->width; 1244 a.in.dsty = row * fp->height; 1245 a.in.height = fp->height; 1246 a.in.width = fp->width; 1247 1248 (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 1249 } 1250 1251 return 0; 1252 } 1253 1254 int 1255 sti_copycols(void *v, int row, int srccol, int dstcol, int ncols) 1256 { 1257 struct sti_screen *scr = (struct sti_screen *)v; 1258 struct sti_font *fp = &scr->scr_curfont; 1259 1260 sti_bmove(scr, 1261 srccol * fp->width, row * fp->height, 1262 dstcol * fp->width, row * fp->height, 1263 fp->height, ncols * fp->width, bmf_copy); 1264 1265 return 0; 1266 } 1267 1268 int 1269 sti_erasecols(void *v, int row, int startcol, int ncols, long attr) 1270 { 1271 struct sti_screen *scr = (struct sti_screen *)v; 1272 struct sti_font *fp = &scr->scr_curfont; 1273 1274 sti_bmove(scr, 1275 startcol * fp->width, row * fp->height, 1276 startcol * fp->width, row * fp->height, 1277 fp->height, ncols * fp->width, bmf_clear); 1278 1279 return 0; 1280 } 1281 1282 int 1283 sti_copyrows(void *v, int srcrow, int dstrow, int nrows) 1284 { 1285 struct sti_screen *scr = (struct sti_screen *)v; 1286 struct sti_font *fp = &scr->scr_curfont; 1287 1288 sti_bmove(scr, 0, srcrow * fp->height, 0, dstrow * fp->height, 1289 nrows * fp->height, scr->scr_cfg.scr_width, bmf_copy); 1290 1291 return 0; 1292 } 1293 1294 int 1295 sti_eraserows(void *v, int srcrow, int nrows, long attr) 1296 { 1297 struct sti_screen *scr = (struct sti_screen *)v; 1298 struct sti_font *fp = &scr->scr_curfont; 1299 1300 sti_bmove(scr, 0, srcrow * fp->height, 0, srcrow * fp->height, 1301 nrows * fp->height, scr->scr_cfg.scr_width, bmf_clear); 1302 1303 return 0; 1304 } 1305 1306 int 1307 sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr) 1308 { 1309 #if 0 1310 struct sti_screen *scr = (struct sti_screen *)v; 1311 #endif 1312 1313 *pattr = flags & WSATTR_REVERSE; 1314 return 0; 1315 } 1316 1317 void 1318 sti_unpack_attr(void *v, long attr, int *fg, int *bg, int *ul) 1319 { 1320 #if 0 1321 struct sti_screen *scr = (struct sti_screen *)v; 1322 #endif 1323 1324 if (attr & WSATTR_REVERSE) { 1325 *fg = STI_COLOUR_BLACK; 1326 *bg = STI_COLOUR_WHITE; 1327 } else { 1328 *fg = STI_COLOUR_WHITE; 1329 *bg = STI_COLOUR_BLACK; 1330 } 1331 if (ul != NULL) 1332 *ul = 0; 1333 } 1334