123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634 |
- /* $OpenBSD: bmd.c,v 1.4 2013/10/29 21:49:07 miod Exp $ */
- /* $NetBSD: bmd.c,v 1.2 2013/01/20 13:35:43 tsutsui Exp $ */
- /*
- * Copyright (c) 1992 OMRON Corporation.
- *
- * This code is derived from software contributed to Berkeley by
- * OMRON Corporation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)bmd.c 8.2 (Berkeley) 8/15/93
- */
- /*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * OMRON Corporation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)bmd.c 8.2 (Berkeley) 8/15/93
- */
- /*
- * bmd.c --- Bitmap-Display raw-level driver routines
- *
- * by A.Fujita, SEP-09-1992
- */
- #include <sys/param.h>
- #include <machine/board.h>
- #include <luna88k/stand/boot/samachdep.h>
- /*
- * RFCNT register
- */
- union bmd_rfcnt {
- struct {
- short rfc_hcnt;
- short rfc_vcnt;
- } p;
- uint32_t u;
- };
- #define isprint(c) ((c) >= 0x20 && (c) < 0x7f)
- /*
- * Width & Height
- */
- #define PB_WIDTH 2048 /* Plane Width (Bit) */
- #define PB_HEIGHT 1024 /* Plane Height (Bit) */
- #define PS_WIDTH 128 /* Plane Width (Short) */
- #define P_WIDTH 256 /* Plane Width (Byte) */
- #define SB_WIDTH 1280 /* Screen Width (Bit) */
- #define SB_HEIGHT 1024 /* Screen Height (Bit) */
- #define SS_WIDTH 80 /* Screen Width (Short) */
- #define S_WIDTH 160 /* Screen Width (Byte) */
- #define FB_WIDTH 12 /* Font Width (Bit) */
- #define FB_HEIGHT 20 /* Font Height (Bit) */
- #define NEXT_LINE(addr) ((addr) + (PS_WIDTH * FB_HEIGHT))
- #define SKIP_NEXT_LINE(addr) (addr) += (PS_WIDTH - SS_WIDTH)
- void bmd_draw_char(char *, char *, int, int, int);
- void bmd_reverse_char(char *, char *, int, int);
- void bmd_erase_char(char *, char *, int, int);
- void bmd_erase_screen(volatile u_short *);
- void bmd_scroll_screen(volatile u_short *, volatile u_short *,
- int, int, int, int);
- struct bmd_linec {
- struct bmd_linec *bl_next;
- struct bmd_linec *bl_prev;
- int bl_col;
- int bl_end;
- u_char bl_line[128];
- };
- struct bmd_softc {
- int bc_stat;
- char *bc_raddr;
- char *bc_waddr;
- int bc_xmin;
- int bc_xmax;
- int bc_ymin;
- int bc_ymax;
- int bc_col;
- int bc_row;
- struct bmd_linec *bc_bl;
- char bc_escseq[8];
- char *bc_esc;
- void (*bc_escape)(int);
- };
- #define STAT_NORMAL 0x0000
- #define STAT_ESCAPE 0x0001
- #define STAT_INSERT 0x0100
- struct bmd_softc bmd_softc;
- struct bmd_linec bmd_linec[52];
- void bmd_escape(int);
- void bmd_escape_0(int);
- void bmd_escape_1(int);
- /*
- * Escape-Sequence
- */
- void
- bmd_escape(int c)
- {
- struct bmd_softc *bp = &bmd_softc;
- switch (c) {
- case '[':
- bp->bc_escape = bmd_escape_0;
- break;
- default:
- bp->bc_stat &= ~STAT_ESCAPE;
- bp->bc_esc = &bp->bc_escseq[0];
- bp->bc_escape = bmd_escape;
- break;
- }
- }
- void
- bmd_escape_0(int c)
- {
- struct bmd_softc *bp = &bmd_softc;
- struct bmd_linec *bq = bp->bc_bl;
- switch (c) {
- case 'A':
- if (bp->bc_row > bp->bc_ymin) {
- bp->bc_row--;
- }
- break;
- case 'C':
- if (bq->bl_col < bp->bc_xmax - 1) {
- bq->bl_col++;
- }
- break;
- case 'K':
- if (bq->bl_col < bp->bc_xmax) {
- int col;
- for (col = bq->bl_col; col < bp->bc_xmax; col++)
- bmd_erase_char(bp->bc_raddr,
- bp->bc_waddr,
- col, bp->bc_row);
- }
- bq->bl_end = bq->bl_col;
- break;
- case 'H':
- bq->bl_col = bq->bl_end = bp->bc_xmin;
- bp->bc_row = bp->bc_ymin;
- break;
- default:
- /*
- *bp->bc_esc++ = c;
- bp->bc_escape = bmd_escape_1;
- return;
- */
- break;
- }
- bp->bc_stat &= ~STAT_ESCAPE;
- bp->bc_esc = &bp->bc_escseq[0];
- bp->bc_escape = bmd_escape;
- }
- void
- bmd_escape_1(int c)
- {
- struct bmd_softc *bp = &bmd_softc;
- struct bmd_linec *bq = bp->bc_bl;
- int col = 0, row = 0;
- char *p;
- switch (c) {
- case 'J':
- bp->bc_stat &= ~STAT_ESCAPE;
- bp->bc_esc = &bp->bc_escseq[0];
- bp->bc_escape = bmd_escape;
- break;
- case 'H':
- for (p = &bp->bc_escseq[0]; *p != ';'; p++)
- row = (row * 10) + (*p - 0x30);
- p++;
- for (p = &bp->bc_escseq[0]; p != bp->bc_esc; p++)
- col = (col * 10) + (*p - 0x30);
- bq->bl_col = col + bp->bc_xmin;
- bp->bc_row = row + bp->bc_ymin;
- bp->bc_stat &= ~STAT_ESCAPE;
- bp->bc_esc = &bp->bc_escseq[0];
- bp->bc_escape = bmd_escape;
- break;
- default:
- *bp->bc_esc++ = c;
- break;
- }
- }
- /*
- * Entry Routine
- */
- void
- bmdinit(void)
- {
- volatile uint32_t *bmd_rfcnt = (volatile uint32_t *)BMAP_RFCNT;
- volatile long *bmd_bmsel = (volatile long *)BMAP_BMSEL;
- struct bmd_softc *bp = &bmd_softc;
- struct bmd_linec *bq;
- int i;
- union bmd_rfcnt rfcnt;
- /*
- * adjust plane position
- */
- bp->bc_raddr = (char *)(BMAP_BMAP0 + 8); /* plane-0 hardware address */
- bp->bc_waddr = (char *)(BMAP_BMP + 8); /* common bitmap hardware address */
- rfcnt.p.rfc_hcnt = 7; /* shift left 16 dot */
- rfcnt.p.rfc_vcnt = -27; /* shift down 1 dot */
- *bmd_rfcnt = rfcnt.u;
- bp->bc_stat = STAT_NORMAL;
- bp->bc_xmin = 8;
- bp->bc_xmax = 96;
- bp->bc_ymin = 2;
- bp->bc_ymax = 48;
- bp->bc_row = bp->bc_ymin;
- for (i = bp->bc_ymin; i < bp->bc_ymax; i++) {
- bmd_linec[i].bl_next = &bmd_linec[i+1];
- bmd_linec[i].bl_prev = &bmd_linec[i-1];
- }
- bmd_linec[bp->bc_ymax-1].bl_next = &bmd_linec[bp->bc_ymin];
- bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax-1];
- bq = bp->bc_bl = &bmd_linec[bp->bc_ymin];
- bq->bl_col = bq->bl_end = bp->bc_xmin;
- bp->bc_col = bp->bc_xmin;
- bp->bc_esc = &bp->bc_escseq[0];
- bp->bc_escape = bmd_escape;
- *bmd_bmsel = 0xff; /* all planes */
- bmd_erase_screen((u_short *) bp->bc_waddr); /* clear screen */
- *bmd_bmsel = 0x01; /* 1 plane */
- /* turn on cursole */
- bmd_reverse_char(bp->bc_raddr,
- bp->bc_waddr,
- bq->bl_col, bp->bc_row);
- }
- void
- bmdadjust(short hcnt, short vcnt)
- {
- volatile uint32_t *bmd_rfcnt = (volatile uint32_t *)BMAP_RFCNT;
- union bmd_rfcnt rfcnt;
- printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt);
- rfcnt.p.rfc_hcnt = hcnt; /* shift left 16 dot */
- rfcnt.p.rfc_vcnt = vcnt; /* shift down 1 dot */
- *bmd_rfcnt = rfcnt.u;
- }
- int
- bmdputc(int c)
- {
- struct bmd_softc *bp = &bmd_softc;
- struct bmd_linec *bq = bp->bc_bl;
- int i;
- c &= 0x7F;
- /* turn off cursole */
- bmd_reverse_char(bp->bc_raddr,
- bp->bc_waddr,
- bq->bl_col, bp->bc_row);
- /* do escape-sequence */
- if (bp->bc_stat & STAT_ESCAPE) {
- *bp->bc_esc++ = c;
- (*bp->bc_escape)(c);
- goto done;
- }
- if (isprint(c)) {
- bmd_draw_char(bp->bc_raddr, bp->bc_waddr,
- bq->bl_col, bp->bc_row, c);
- bq->bl_col++;
- bq->bl_end++;
- if (bq->bl_col >= bp->bc_xmax) {
- bq->bl_col = bq->bl_end = bp->bc_xmin;
- bp->bc_row++;
- if (bp->bc_row >= bp->bc_ymax) {
- bmd_scroll_screen((u_short *) bp->bc_raddr,
- (u_short *) bp->bc_waddr,
- bp->bc_xmin, bp->bc_xmax,
- bp->bc_ymin, bp->bc_ymax);
- bp->bc_row = bp->bc_ymax - 1;
- }
- }
- } else {
- switch (c) {
- case 0x08: /* BS */
- if (bq->bl_col > bp->bc_xmin) {
- bq->bl_col--;
- }
- break;
- case 0x09: /* HT */
- case 0x0B: /* VT */
- i = ((bq->bl_col / 8) + 1) * 8;
- if (i < bp->bc_xmax) {
- bq->bl_col = bq->bl_end = i;
- }
- break;
- case 0x0A: /* NL */
- bp->bc_row++;
- if (bp->bc_row >= bp->bc_ymax) {
- bmd_scroll_screen((u_short *) bp->bc_raddr,
- (u_short *) bp->bc_waddr,
- bp->bc_xmin, bp->bc_xmax,
- bp->bc_ymin, bp->bc_ymax);
- bp->bc_row = bp->bc_ymax - 1;
- }
- break;
- case 0x0D: /* CR */
- bq->bl_col = bp->bc_xmin;
- break;
- case 0x1b: /* ESC */
- bp->bc_stat |= STAT_ESCAPE;
- *bp->bc_esc++ = 0x1b;
- break;
- case 0x7F: /* DEL */
- if (bq->bl_col > bp->bc_xmin) {
- bq->bl_col--;
- bmd_erase_char(bp->bc_raddr,
- bp->bc_waddr,
- bq->bl_col, bp->bc_row);
- }
- break;
- default:
- break;
- }
- }
- done:
- /* turn on cursole */
- bmd_reverse_char(bp->bc_raddr,
- bp->bc_waddr,
- bq->bl_col, bp->bc_row);
- return(c);
- }
- void
- bmdclear(void)
- {
- struct bmd_softc *bp = &bmd_softc;
- struct bmd_linec *bq = bp->bc_bl;
- bmd_erase_screen((u_short *) bp->bc_waddr); /* clear screen */
- bq->bl_col = bq->bl_end = bp->bc_xmin;
- bp->bc_row = bp->bc_ymin;
- bmd_reverse_char(bp->bc_raddr,
- bp->bc_waddr,
- bq->bl_col, bp->bc_row); /* turn on cursole */
- }
- /*
- * charactor operation routines
- */
- void
- bmd_draw_char(char *raddr, char *waddr, int col, int row, int c)
- {
- volatile u_short *p, *q;
- const u_short *fp;
- int i;
- fp = &bmdfont[c][0];
- switch (col % 4) {
- case 0:
- p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
- q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
- for (i = 0; i < FB_HEIGHT; i++) {
- *q = (*p & 0x000F) | (*fp & 0xFFF0);
- p += 128;
- q += 128;
- fp++;
- }
- break;
- case 1:
- p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
- q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
- for (i = 0; i < FB_HEIGHT; i++) {
- q[0] = (p[0] & 0xFFF0) | ((*fp & 0xF000) >> 12);
- q[1] = (p[1] & 0x00FF) | ((*fp & 0x0FF0) << 4);
- p += 128;
- q += 128;
- fp++;
- }
- break;
- case 2:
- p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
- q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
- for (i = 0; i < FB_HEIGHT; i++) {
- q[0] = (p[0] & 0xFF00) | ((*fp & 0xFF00) >> 8);
- q[1] = (p[1] & 0x0FFF) | ((*fp & 0x00F0) << 8);
- p += 128;
- q += 128;
- fp++;
- }
- break;
- case 3:
- p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
- q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
- for (i = 0; i < FB_HEIGHT; i++) {
- *q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4);
- p += 128;
- q += 128;
- fp++;
- }
- break;
- default:
- break;
- }
- }
- void
- bmd_reverse_char(char *raddr, char *waddr, int col, int row)
- {
- volatile u_short *p, *q;
- int i;
- switch (col%4) {
- case 0:
- p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
- q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
- for (i = 0; i < FB_HEIGHT; i++) {
- *q = (*p & 0x000F) | (~(*p) & 0xFFF0);
- p += 128;
- q += 128;
- }
- break;
- case 1:
- p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
- q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
- for (i = 0; i < FB_HEIGHT; i++) {
- q[0] = (p[0] & 0xFFF0) | (~p[0] & 0x000F);
- q[1] = (p[1] & 0x00FF) | (~p[1] & 0xFF00);
- p += 128;
- q += 128;
- }
- break;
- case 2:
- p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
- q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
- for (i = 0; i < FB_HEIGHT; i++) {
- q[0] = (p[0] & 0xFF00) | (~p[0] & 0x00FF);
- q[1] = (p[1] & 0x0FFF) | (~p[1] & 0xF000);
- p += 128;
- q += 128;
- }
- break;
- case 3:
- p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
- q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
- for (i = 0; i < FB_HEIGHT; i++) {
- *q = (*p & 0xF000) | (~(*p) & 0x0FFF);
- p += 128;
- q += 128;
- }
- break;
- default:
- break;
- }
- }
- void
- bmd_erase_char(char *raddr, char *waddr, int col, int row)
- {
- bmd_draw_char(raddr, waddr, col, row, 0);
- return;
- }
- /*
- * screen operation routines
- */
- void
- bmd_erase_screen(volatile u_short *p)
- {
- int i, j;
- for (i = 0; i < SB_HEIGHT; i++) {
- for (j = 0; j < SS_WIDTH; j++)
- *p++ = 0;
- SKIP_NEXT_LINE(p);
- }
- return;
- }
- void
- bmd_scroll_screen(volatile u_short *p, volatile u_short *q,
- int xmin, int xmax, int ymin, int ymax)
- {
- int i, j;
- p += ((PS_WIDTH * FB_HEIGHT) * (ymin + 1));
- q += ((PS_WIDTH * FB_HEIGHT) * ymin);
- for (i = 0; i < ((ymax - ymin -1) * FB_HEIGHT); i++) {
- for (j = 0; j < SS_WIDTH; j++) {
- *q++ = *p++;
- }
- p += (PS_WIDTH - SS_WIDTH);
- q += (PS_WIDTH - SS_WIDTH);
- }
- for (i = 0; i < FB_HEIGHT; i++) {
- for (j = 0; j < SS_WIDTH; j++) {
- *q++ = 0;
- }
- q += (PS_WIDTH - SS_WIDTH);
- }
- }
|