OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [video/] [newport_con.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * newport_con.c: Abscon for newport hardware
3
 *
4
 * (C) 1998 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
5
 * (C) 1999 Ulf Carlsson (ulfc@thepuffingruop.com)
6
 *
7
 * This driver is based on sgicons.c and cons_newport.
8
 *
9
 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
10
 * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
11
 */
12
#include <linux/init.h>
13
#include <linux/kernel.h>
14
#include <linux/errno.h>
15
#include <linux/tty.h>
16
#include <linux/kd.h>
17
#include <linux/selection.h>
18
#include <linux/console.h>
19
#include <linux/console_struct.h>
20
#include <linux/vt_kern.h>
21
#include <linux/mm.h>
22
#include <linux/module.h>
23
#include <linux/slab.h>
24
 
25
#include <asm/uaccess.h>
26
#include <asm/system.h>
27
#include <asm/page.h>
28
#include <asm/pgtable.h>
29
#include <video/newport.h>
30
#define INCLUDE_LINUX_LOGO_DATA
31
#include <asm/linux_logo.h>
32
 
33
#include <video/font.h>
34
 
35
#define LOGO_W          80
36
#define LOGO_H          80
37
 
38
extern struct fbcon_font_desc font_vga_8x16;
39
extern unsigned long sgi_gfxaddr;
40
 
41
#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
42
 
43
/* borrowed from fbcon.c */
44
#define REFCOUNT(fd)    (((int *)(fd))[-1])
45
#define FNTSIZE(fd)     (((int *)(fd))[-2])
46
#define FNTCHARCNT(fd)  (((int *)(fd))[-3])
47
#define FONT_EXTRA_WORDS 3
48
 
49
static unsigned char *font_data[MAX_NR_CONSOLES];
50
 
51
static struct newport_regs *npregs;
52
 
53
static int logo_active;
54
static int topscan;
55
static int xcurs_correction = 29;
56
static int newport_xsize;
57
static int newport_ysize;
58
 
59
static int newport_set_def_font(int unit, struct console_font_op *op);
60
 
61
#define BMASK(c) (c << 24)
62
 
63
#define RENDER(regs, cp) do { \
64
(regs)->go.zpattern = BMASK((cp)[0x0]); (regs)->go.zpattern = BMASK((cp)[0x1]); \
65
(regs)->go.zpattern = BMASK((cp)[0x2]); (regs)->go.zpattern = BMASK((cp)[0x3]); \
66
(regs)->go.zpattern = BMASK((cp)[0x4]); (regs)->go.zpattern = BMASK((cp)[0x5]); \
67
(regs)->go.zpattern = BMASK((cp)[0x6]); (regs)->go.zpattern = BMASK((cp)[0x7]); \
68
(regs)->go.zpattern = BMASK((cp)[0x8]); (regs)->go.zpattern = BMASK((cp)[0x9]); \
69
(regs)->go.zpattern = BMASK((cp)[0xa]); (regs)->go.zpattern = BMASK((cp)[0xb]); \
70
(regs)->go.zpattern = BMASK((cp)[0xc]); (regs)->go.zpattern = BMASK((cp)[0xd]); \
71
(regs)->go.zpattern = BMASK((cp)[0xe]); (regs)->go.zpattern = BMASK((cp)[0xf]); \
72
} while(0)
73
 
74
#define TESTVAL 0xdeadbeef
75
#define XSTI_TO_FXSTART(val) (((val) & 0xffff) << 11)
76
 
77
static inline void newport_render_background(int xstart, int ystart,
78
                                             int xend, int yend, int ci)
79
{
80
        newport_wait();
81
        npregs->set.wrmask = 0xffffffff;
82
        npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
83
                                 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
84
                                 | NPORT_DMODE0_STOPY);
85
        npregs->set.colori = ci;
86
        npregs->set.xystarti =
87
            (xstart << 16) | ((ystart + topscan) & 0x3ff);
88
        npregs->go.xyendi =
89
            ((xend + 7) << 16) | ((yend + topscan + 15) & 0x3ff);
90
}
91
 
92
static inline void newport_init_cmap(void)
93
{
94
        unsigned short i;
95
 
96
        for (i = 0; i < 16; i++) {
97
                newport_bfwait();
98
                newport_cmap_setaddr(npregs, color_table[i]);
99
                newport_cmap_setrgb(npregs,
100
                                    default_red[i],
101
                                    default_grn[i], default_blu[i]);
102
        }
103
}
104
 
105
static inline void newport_show_logo(void)
106
{
107
        unsigned long i;
108
 
109
        for (i = 0; i < LINUX_LOGO_COLORS; i++) {
110
                newport_bfwait();
111
                newport_cmap_setaddr(npregs, i + 0x20);
112
                newport_cmap_setrgb(npregs,
113
                                    linux_logo_red[i],
114
                                    linux_logo_green[i],
115
                                    linux_logo_blue[i]);
116
        }
117
 
118
        newport_wait();
119
        npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
120
                                 NPORT_DMODE0_CHOST);
121
 
122
        npregs->set.xystarti = ((newport_xsize - LOGO_W) << 16) | (0);
123
        npregs->set.xyendi = ((newport_xsize - 1) << 16);
124
        newport_wait();
125
 
126
        for (i = 0; i < LOGO_W * LOGO_H; i++)
127
                npregs->go.hostrw0 = linux_logo[i] << 24;
128
}
129
 
130
static inline void newport_clear_screen(int xstart, int ystart, int xend,
131
                                        int yend, int ci)
132
{
133
        if (logo_active)
134
                return;
135
 
136
        newport_wait();
137
        npregs->set.wrmask = 0xffffffff;
138
        npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
139
                                 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
140
                                 | NPORT_DMODE0_STOPY);
141
        npregs->set.colori = ci;
142
        npregs->set.xystarti = (xstart << 16) | ystart;
143
        npregs->go.xyendi = (xend << 16) | yend;
144
}
145
 
146
static inline void newport_clear_lines(int ystart, int yend, int ci)
147
{
148
        ystart = ((ystart << 4) + topscan) & 0x3ff;
149
        yend = ((yend << 4) + topscan + 15) & 0x3ff;
150
        newport_clear_screen(0, ystart, 1280 + 63, yend, ci);
151
}
152
 
153
void newport_reset(void)
154
{
155
        unsigned short treg;
156
        int i;
157
 
158
        newport_wait();
159
        treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
160
        newport_vc2_set(npregs, VC2_IREG_CONTROL,
161
                        (treg | VC2_CTRL_EVIDEO));
162
 
163
        treg = newport_vc2_get(npregs, VC2_IREG_CENTRY);
164
        newport_vc2_set(npregs, VC2_IREG_RADDR, treg);
165
        npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
166
                               NPORT_DMODE_W2 | VC2_PROTOCOL);
167
        for (i = 0; i < 128; i++) {
168
                newport_bfwait();
169
                if (i == 92 || i == 94)
170
                        npregs->set.dcbdata0.byshort.s1 = 0xff00;
171
                else
172
                        npregs->set.dcbdata0.byshort.s1 = 0x0000;
173
        }
174
 
175
        newport_init_cmap();
176
 
177
        /* turn off popup plane */
178
        npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
179
                               XM9_CRS_CONFIG | NPORT_DMODE_W1);
180
        npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;
181
        npregs->set.dcbmode = (DCB_XMAP1 | R_DCB_XMAP9_PROTOCOL |
182
                               XM9_CRS_CONFIG | NPORT_DMODE_W1);
183
        npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;
184
 
185
        topscan = 0;
186
        npregs->cset.topscan = 0x3ff;
187
        npregs->cset.xywin = (4096 << 16) | 4096;
188
 
189
        /* Clear the screen. */
190
        newport_clear_screen(0, 0, 1280 + 63, 1024, 0);
191
}
192
 
193
/*
194
 * calculate the actual screen size by reading
195
 * the video timing out of the VC2
196
 */
197
void newport_get_screensize(void)
198
{
199
        int i, cols;
200
        unsigned short ventry, treg;
201
        unsigned short linetable[128];  /* should be enough */
202
 
203
        ventry = newport_vc2_get(npregs, VC2_IREG_VENTRY);
204
        newport_vc2_set(npregs, VC2_IREG_RADDR, ventry);
205
        npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
206
                               NPORT_DMODE_W2 | VC2_PROTOCOL);
207
        for (i = 0; i < 128; i++) {
208
                newport_bfwait();
209
                linetable[i] = npregs->set.dcbdata0.byshort.s1;
210
        }
211
 
212
        newport_xsize = newport_ysize = 0;
213
        for (i = 0; linetable[i + 1] && (i < sizeof(linetable)); i += 2) {
214
                cols = 0;
215
                newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]);
216
                npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
217
                                       NPORT_DMODE_W2 | VC2_PROTOCOL);
218
                do {
219
                        newport_bfwait();
220
                        treg = npregs->set.dcbdata0.byshort.s1;
221
                        if ((treg & 1) == 0)
222
                                cols += (treg >> 7) & 0xfe;
223
                        if ((treg & 0x80) == 0) {
224
                                newport_bfwait();
225
                                treg = npregs->set.dcbdata0.byshort.s1;
226
                        }
227
                } while ((treg & 0x8000) == 0);
228
                if (cols) {
229
                        if (cols > newport_xsize)
230
                                newport_xsize = cols;
231
                        newport_ysize += linetable[i + 1];
232
                }
233
        }
234
        printk("NG1: Screensize %dx%d\n", newport_xsize, newport_ysize);
235
}
236
 
237
static void newport_get_revisions(void)
238
{
239
        unsigned int tmp;
240
        unsigned int board_rev;
241
        unsigned int rex3_rev;
242
        unsigned int vc2_rev;
243
        unsigned int cmap_rev;
244
        unsigned int xmap9_rev;
245
        unsigned int bt445_rev;
246
        unsigned int bitplanes;
247
 
248
        rex3_rev = npregs->cset.status & NPORT_STAT_VERS;
249
 
250
        npregs->set.dcbmode = (DCB_CMAP0 | NCMAP_PROTOCOL |
251
                               NCMAP_REGADDR_RREG | NPORT_DMODE_W1);
252
        tmp = npregs->set.dcbdata0.bybytes.b3;
253
        cmap_rev = tmp & 7;
254
        board_rev = (tmp >> 4) & 7;
255
        bitplanes = ((board_rev > 1) && (tmp & 0x80)) ? 8 : 24;
256
 
257
        npregs->set.dcbmode = (DCB_CMAP1 | NCMAP_PROTOCOL |
258
                               NCMAP_REGADDR_RREG | NPORT_DMODE_W1);
259
        tmp = npregs->set.dcbdata0.bybytes.b3;
260
        if ((tmp & 7) < cmap_rev)
261
                cmap_rev = (tmp & 7);
262
 
263
        vc2_rev = (newport_vc2_get(npregs, VC2_IREG_CONFIG) >> 5) & 7;
264
 
265
        npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
266
                               XM9_CRS_REVISION | NPORT_DMODE_W1);
267
        xmap9_rev = npregs->set.dcbdata0.bybytes.b3 & 7;
268
 
269
        npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |
270
                               BT445_CSR_ADDR_REG | NPORT_DMODE_W1);
271
        npregs->set.dcbdata0.bybytes.b3 = BT445_REVISION_REG;
272
        npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |
273
                               BT445_CSR_REVISION | NPORT_DMODE_W1);
274
        bt445_rev = (npregs->set.dcbdata0.bybytes.b3 >> 4) - 0x0a;
275
 
276
#define L(a)     (char)('A'+(a))
277
        printk
278
            ("NG1: Revision %d, %d bitplanes, REX3 revision %c, VC2 revision %c, xmap9 revision %c, cmap revision %c, bt445 revision %c\n",
279
             board_rev, bitplanes, L(rex3_rev), L(vc2_rev), L(xmap9_rev),
280
             L(cmap_rev ? (cmap_rev + 1) : 0), L(bt445_rev));
281
#undef L
282
 
283
        if (board_rev == 3)     /* I don't know all affected revisions */
284
                xcurs_correction = 21;
285
}
286
 
287
/* Can't be __init, take_over_console may call it later */
288
static const char *newport_startup(void)
289
{
290
        int i;
291
 
292
        if (!sgi_gfxaddr)
293
                return NULL;
294
        npregs = (struct newport_regs *) (KSEG1 + sgi_gfxaddr);
295
        npregs->cset.config = NPORT_CFG_GD0;
296
 
297
        if (newport_wait()) {
298
                return NULL;
299
        }
300
 
301
        npregs->set.xstarti = TESTVAL;
302
        if (npregs->set._xstart.word != XSTI_TO_FXSTART(TESTVAL))
303
                return NULL;
304
 
305
        for (i = 0; i < MAX_NR_CONSOLES; i++)
306
                font_data[i] = FONT_DATA;
307
 
308
        newport_reset();
309
        newport_get_revisions();
310
        newport_get_screensize();
311
 
312
        return "SGI Newport";
313
}
314
 
315
static void newport_init(struct vc_data *vc, int init)
316
{
317
        vc->vc_cols = newport_xsize / 8;
318
        vc->vc_rows = newport_ysize / 16;
319
        vc->vc_can_do_color = 1;
320
}
321
 
322
static void newport_deinit(struct vc_data *c)
323
{
324
        int i;
325
 
326
        /* free memory used by user font */
327
        for (i = 0; i < MAX_NR_CONSOLES; i++)
328
                newport_set_def_font(i, NULL);
329
}
330
 
331
static void newport_clear(struct vc_data *vc, int sy, int sx, int height,
332
                          int width)
333
{
334
        int xend = ((sx + width) << 3) - 1;
335
        int ystart = ((sy << 4) + topscan) & 0x3ff;
336
        int yend = (((sy + height) << 4) + topscan - 1) & 0x3ff;
337
 
338
        if (logo_active)
339
                return;
340
 
341
        if (ystart < yend) {
342
                newport_clear_screen(sx << 3, ystart, xend, yend,
343
                                     (vc->vc_color & 0xf0) >> 4);
344
        } else {
345
                newport_clear_screen(sx << 3, ystart, xend, 1023,
346
                                     (vc->vc_color & 0xf0) >> 4);
347
                newport_clear_screen(sx << 3, 0, xend, yend,
348
                                     (vc->vc_color & 0xf0) >> 4);
349
        }
350
}
351
 
352
static void newport_putc(struct vc_data *vc, int charattr, int ypos,
353
                         int xpos)
354
{
355
        unsigned char *p;
356
 
357
        p = &font_data[vc->vc_num][(charattr & 0xff) << 4];
358
        charattr = (charattr >> 8) & 0xff;
359
        xpos <<= 3;
360
        ypos <<= 4;
361
 
362
        newport_render_background(xpos, ypos, xpos, ypos,
363
                                  (charattr & 0xf0) >> 4);
364
 
365
        /* Set the color and drawing mode. */
366
        newport_wait();
367
        npregs->set.colori = charattr & 0xf;
368
        npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
369
                                 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
370
                                 NPORT_DMODE0_L32);
371
 
372
        /* Set coordinates for bitmap operation. */
373
        npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);
374
        npregs->set.xyendi = ((xpos + 7) << 16);
375
        newport_wait();
376
 
377
        /* Go, baby, go... */
378
        RENDER(npregs, p);
379
}
380
 
381
static void newport_putcs(struct vc_data *vc, const unsigned short *s,
382
                          int count, int ypos, int xpos)
383
{
384
        int i;
385
        int charattr;
386
        unsigned char *p;
387
 
388
        charattr = (scr_readw(s) >> 8) & 0xff;
389
 
390
        xpos <<= 3;
391
        ypos <<= 4;
392
 
393
        if (!logo_active)
394
                /* Clear the area behing the string */
395
                newport_render_background(xpos, ypos,
396
                                          xpos + ((count - 1) << 3), ypos,
397
                                          (charattr & 0xf0) >> 4);
398
 
399
        newport_wait();
400
 
401
        /* Set the color and drawing mode. */
402
        npregs->set.colori = charattr & 0xf;
403
        npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
404
                                 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
405
                                 NPORT_DMODE0_L32);
406
 
407
        for (i = 0; i < count; i++, xpos += 8) {
408
                p = &font_data[vc->vc_num][(scr_readw(s++) & 0xff) << 4];
409
 
410
                newport_wait();
411
 
412
                /* Set coordinates for bitmap operation. */
413
                npregs->set.xystarti =
414
                    (xpos << 16) | ((ypos + topscan) & 0x3ff);
415
                npregs->set.xyendi = ((xpos + 7) << 16);
416
 
417
                /* Go, baby, go... */
418
                RENDER(npregs, p);
419
        }
420
}
421
 
422
static void newport_cursor(struct vc_data *vc, int mode)
423
{
424
        unsigned short treg;
425
        int xcurs, ycurs;
426
 
427
        switch (mode) {
428
        case CM_ERASE:
429
                treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
430
                newport_vc2_set(npregs, VC2_IREG_CONTROL,
431
                                (treg & ~(VC2_CTRL_ECDISP)));
432
                break;
433
 
434
        case CM_MOVE:
435
        case CM_DRAW:
436
                treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
437
                newport_vc2_set(npregs, VC2_IREG_CONTROL,
438
                                (treg | VC2_CTRL_ECDISP));
439
                xcurs = (vc->vc_pos - vc->vc_visible_origin) / 2;
440
                ycurs = ((xcurs / vc->vc_cols) << 4) + 31;
441
                xcurs = ((xcurs % vc->vc_cols) << 3) + xcurs_correction;
442
                newport_vc2_set(npregs, VC2_IREG_CURSX, xcurs);
443
                newport_vc2_set(npregs, VC2_IREG_CURSY, ycurs);
444
        }
445
}
446
 
447
static int newport_switch(struct vc_data *vc)
448
{
449
        static int logo_drawn = 0;
450
 
451
        topscan = 0;
452
        npregs->cset.topscan = 0x3ff;
453
 
454
        if (!logo_drawn) {
455
                newport_show_logo();
456
                logo_drawn = 1;
457
                logo_active = 1;
458
        }
459
 
460
        return 1;
461
}
462
 
463
static int newport_blank(struct vc_data *c, int blank)
464
{
465
        unsigned short treg;
466
 
467
        if (blank == 0) {
468
                /* unblank console */
469
                treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
470
                newport_vc2_set(npregs, VC2_IREG_CONTROL,
471
                                (treg | VC2_CTRL_EDISP));
472
        } else {
473
                /* blank console */
474
                treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
475
                newport_vc2_set(npregs, VC2_IREG_CONTROL,
476
                                (treg & ~(VC2_CTRL_EDISP)));
477
        }
478
        return 1;
479
}
480
 
481
static int newport_set_font(int unit, struct console_font_op *op)
482
{
483
        int w = op->width;
484
        int h = op->height;
485
        int size = h * op->charcount;
486
        int i;
487
        unsigned char *new_data, *data = op->data, *p;
488
 
489
        /* ladis: when I grow up, there will be a day... and more sizes will
490
         * be supported ;-) */
491
        if ((w != 8) || (h != 16)
492
            || (op->charcount != 256 && op->charcount != 512))
493
                return -EINVAL;
494
 
495
        if (!(new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size,
496
             GFP_USER))) return -ENOMEM;
497
 
498
        new_data += FONT_EXTRA_WORDS * sizeof(int);
499
        FNTSIZE(new_data) = size;
500
        FNTCHARCNT(new_data) = op->charcount;
501
        REFCOUNT(new_data) = 0;  /* usage counter */
502
 
503
        p = new_data;
504
        for (i = 0; i < op->charcount; i++) {
505
                memcpy(p, data, h);
506
                data += 32;
507
                p += h;
508
        }
509
 
510
        /* check if font is already used by other console */
511
        for (i = 0; i < MAX_NR_CONSOLES; i++) {
512
                if (font_data[i] != FONT_DATA
513
                    && FNTSIZE(font_data[i]) == size
514
                    && !memcmp(font_data[i], new_data, size)) {
515
                        kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
516
                        /* current font is the same as the new one */
517
                        if (i == unit)
518
                                return 0;
519
                        new_data = font_data[i];
520
                        break;
521
                }
522
        }
523
        /* old font is user font */
524
        if (font_data[unit] != FONT_DATA) {
525
                if (--REFCOUNT(font_data[unit]) == 0)
526
                        kfree(font_data[unit] -
527
                              FONT_EXTRA_WORDS * sizeof(int));
528
        }
529
        REFCOUNT(new_data)++;
530
        font_data[unit] = new_data;
531
 
532
        return 0;
533
}
534
 
535
static int newport_set_def_font(int unit, struct console_font_op *op)
536
{
537
        if (font_data[unit] != FONT_DATA) {
538
                if (--REFCOUNT(font_data[unit]) == 0)
539
                        kfree(font_data[unit] -
540
                              FONT_EXTRA_WORDS * sizeof(int));
541
                font_data[unit] = FONT_DATA;
542
        }
543
 
544
        return 0;
545
}
546
 
547
static int newport_font_op(struct vc_data *vc, struct console_font_op *op)
548
{
549
        int unit = vc->vc_num;
550
 
551
        switch (op->op) {
552
        case KD_FONT_OP_SET:
553
                return newport_set_font(unit, op);
554
        case KD_FONT_OP_SET_DEFAULT:
555
                return newport_set_def_font(unit, op);
556
        default:
557
                return -ENOSYS;
558
        }
559
}
560
 
561
static int newport_set_palette(struct vc_data *vc, unsigned char *table)
562
{
563
        return -EINVAL;
564
}
565
 
566
static int newport_scrolldelta(struct vc_data *vc, int lines)
567
{
568
        /* there is (nearly) no off-screen memory, so we can't scroll back */
569
        return 0;
570
}
571
 
572
static int newport_scroll(struct vc_data *vc, int t, int b, int dir,
573
                          int lines)
574
{
575
        int count, x, y;
576
        unsigned short *s, *d;
577
        unsigned short chattr;
578
 
579
        logo_active = 0; /* it's time to disable the logo now.. */
580
 
581
        if (t == 0 && b == vc->vc_rows) {
582
                if (dir == SM_UP) {
583
                        topscan = (topscan + (lines << 4)) & 0x3ff;
584
                        newport_clear_lines(vc->vc_rows - lines,
585
                                            vc->vc_rows - 1,
586
                                            (vc->vc_color & 0xf0) >> 4);
587
                } else {
588
                        topscan = (topscan + (-lines << 4)) & 0x3ff;
589
                        newport_clear_lines(0, lines - 1,
590
                                            (vc->vc_color & 0xf0) >> 4);
591
                }
592
                npregs->cset.topscan = (topscan - 1) & 0x3ff;
593
                return 0;
594
        }
595
 
596
        count = (b - t - lines) * vc->vc_cols;
597
        if (dir == SM_UP) {
598
                x = 0;
599
                y = t;
600
                s = (unsigned short *) (vc->vc_origin +
601
                                        vc->vc_size_row * (t + lines));
602
                d = (unsigned short *) (vc->vc_origin +
603
                                        vc->vc_size_row * t);
604
                while (count--) {
605
                        chattr = scr_readw(s++);
606
                        if (chattr != scr_readw(d)) {
607
                                newport_putc(vc, chattr, y, x);
608
                                scr_writew(chattr, d);
609
                        }
610
                        d++;
611
                        if (++x == vc->vc_cols) {
612
                                x = 0;
613
                                y++;
614
                        }
615
                }
616
                d = (unsigned short *) (vc->vc_origin +
617
                                        vc->vc_size_row * (b - lines));
618
                x = 0;
619
                y = b - lines;
620
                for (count = 0; count < (lines * vc->vc_cols); count++) {
621
                        if (scr_readw(d) != vc->vc_video_erase_char) {
622
                                newport_putc(vc, vc->vc_video_erase_char,
623
                                             y, x);
624
                                scr_writew(vc->vc_video_erase_char, d);
625
                        }
626
                        d++;
627
                        if (++x == vc->vc_cols) {
628
                                x = 0;
629
                                y++;
630
                        }
631
                }
632
        } else {
633
                x = vc->vc_cols - 1;
634
                y = b - 1;
635
                s = (unsigned short *) (vc->vc_origin +
636
                                        vc->vc_size_row * (b - lines) - 2);
637
                d = (unsigned short *) (vc->vc_origin +
638
                                        vc->vc_size_row * b - 2);
639
                while (count--) {
640
                        chattr = scr_readw(s--);
641
                        if (chattr != scr_readw(d)) {
642
                                newport_putc(vc, chattr, y, x);
643
                                scr_writew(chattr, d);
644
                        }
645
                        d--;
646
                        if (x-- == 0) {
647
                                x = vc->vc_cols - 1;
648
                                y--;
649
                        }
650
                }
651
                d = (unsigned short *) (vc->vc_origin +
652
                                        vc->vc_size_row * t);
653
                x = 0;
654
                y = t;
655
                for (count = 0; count < (lines * vc->vc_cols); count++) {
656
                        if (scr_readw(d) != vc->vc_video_erase_char) {
657
                                newport_putc(vc, vc->vc_video_erase_char,
658
                                             y, x);
659
                                scr_writew(vc->vc_video_erase_char, d);
660
                        }
661
                        d++;
662
                        if (++x == vc->vc_cols) {
663
                                x = 0;
664
                                y++;
665
                        }
666
                }
667
        }
668
        return 1;
669
}
670
 
671
static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
672
                          int dx, int h, int w)
673
{
674
        short xs, ys, xe, ye, xoffs, yoffs, tmp;
675
 
676
        xs = sx << 3;
677
        xe = ((sx + w) << 3) - 1;
678
        /*
679
         * as bmove is only used to move stuff around in the same line
680
         * (h == 1), we don't care about wrap arounds caused by topscan != 0
681
         */
682
        ys = ((sy << 4) + topscan) & 0x3ff;
683
        ye = (((sy + h) << 4) - 1 + topscan) & 0x3ff;
684
        xoffs = (dx - sx) << 3;
685
        yoffs = (dy - sy) << 4;
686
        if (xoffs > 0) {
687
                /* move to the right, exchange starting points */
688
                tmp = xe;
689
                xe = xs;
690
                xs = tmp;
691
        }
692
        newport_wait();
693
        npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
694
                                 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
695
                                 | NPORT_DMODE0_STOPY);
696
        npregs->set.xystarti = (xs << 16) | ys;
697
        npregs->set.xyendi = (xe << 16) | ye;
698
        npregs->go.xymove = (xoffs << 16) | yoffs;
699
}
700
 
701
static int newport_dummy(struct vc_data *c)
702
{
703
        return 0;
704
}
705
 
706
#define DUMMY (void *) newport_dummy
707
 
708
const struct consw newport_con = {
709
    con_startup:        newport_startup,
710
    con_init:           newport_init,
711
    con_deinit:         newport_deinit,
712
    con_clear:          newport_clear,
713
    con_putc:           newport_putc,
714
    con_putcs:          newport_putcs,
715
    con_cursor:         newport_cursor,
716
    con_scroll:         newport_scroll,
717
    con_bmove:          newport_bmove,
718
    con_switch:         newport_switch,
719
    con_blank:          newport_blank,
720
    con_font_op:        newport_font_op,
721
    con_set_palette:    newport_set_palette,
722
    con_scrolldelta:    newport_scrolldelta,
723
    con_set_origin:     DUMMY,
724
    con_save_screen:    DUMMY
725
};
726
 
727
#ifdef MODULE
728
static int __init newport_console_init(void)
729
{
730
        take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1);
731
 
732
        return 0;
733
}
734
 
735
static void __exit newport_console_exit(void)
736
{
737
        give_up_console(&newport_con);
738
}
739
 
740
module_init(newport_console_init);
741
module_exit(newport_console_exit);
742
#endif
743
 
744
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.