x68kFb.c revision 80c54d45
1/* $NetBSD: x68kFb.c,v 1.3 2020/04/10 16:49:36 tsutsui Exp $ */
2/*-------------------------------------------------------------------------
3 * Copyright (c) 1996 Yasushi Yamasaki
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *-----------------------------------------------------------------------*/
26
27#include "x68k.h"
28
29static void x68kRegSetup(X68kScreenRec *pPriv);
30
31DevPrivateKeyRec x68kScreenPrivateKeyRec;
32
33/*-------------------------------------------------------------------------
34 * function "x68kFbCommonOpen"
35 *
36 *  purpose:  open and map frame buffer, and obtain some FB-specific
37 *            infomation. then set controller to approppriate mode as
38 *            configured in X68kConfig.
39 *  argument: (X68kScreenRec *)pPriv : X68k private screen record
40 *            (const char *)device   : name of frame buffer device
41 *  returns:  (Bool): TRUE  if succeeded
42 *                    FALSE otherwise
43 *-----------------------------------------------------------------------*/
44Bool
45x68kFbCommonOpen(X68kScreenRec *pPriv, const char *device)
46{
47    struct grfinfo gi;
48
49    /* open frame buffer */
50    if ( ( pPriv->fd = open(device, O_RDWR, 0)) < 0) {
51        ErrorF( "Can't open frame buffer" );
52        return FALSE;
53    }
54    /* get frame buffer infomation */
55    if ( ioctl( pPriv->fd, GRFIOCGINFO, &gi ) == -1 ) {
56        ErrorF( "Can't get grfinfo" );
57        return FALSE;
58    }
59    pPriv->mapsize = gi.gd_regsize + gi.gd_fbsize;
60
61    /* map control registers and frame buffer */
62    pPriv->reg = (FbReg *)mmap(0, pPriv->mapsize, PROT_READ | PROT_WRITE,
63                               MAP_FILE | MAP_SHARED, pPriv->fd, 0 );
64    if ( pPriv->reg == (FbReg *)-1) {
65        ErrorF( "Can't map frame buffer" );
66        return FALSE;
67    }
68    pPriv->fb = (uint8_t *)((uint32_t)pPriv->reg + gi.gd_regsize);
69
70    x68kRegSetup( pPriv );
71
72    return TRUE;
73}
74
75/*-------------------------------------------------------------------------
76 * function "x68kFbCommonClose"
77 *
78 *  purpose:  unmap and close frame buffer, and
79 *            change video mode to normal ITE mode
80 *  argument: (X68kScreenRec *)pPriv : X68k private screen record
81 *  returns:  nothing
82 *-----------------------------------------------------------------------*/
83void
84x68kFbCommonClose(X68kScreenRec *pPriv)
85{
86    X68kFbReg graphNone = {
87        { 137,14, 28, 124,
88          567, 5, 40, 552,
89           27, 0,  0,   0,
90            0, 0,  0,   0,
91            0, 0,  0,   0,
92       0x0416, 0,  0,   0, 0 },
93        { 0x0004, 0x21e4, 0x0020 },
94        0
95    };
96    /* change video mode */
97    pPriv->x68kreg = graphNone;
98    x68kRegSetup(pPriv);
99
100    /* unmap and close frame buffer */
101    if ( munmap(__UNVOLATILE(pPriv->reg), pPriv->mapsize) == -1 )
102        ErrorF("Can't unmap frame buffer");
103    close(pPriv->fd);
104}
105
106/*-------------------------------------------------------------------------
107 * function "x68kRegSetup"
108 *
109 *  purpose:  set up CRT controller and Video controller
110 *            with register values in pPriv->x68kreg
111 *  argument: (X68kScreenRec *)pPriv : X68k private screen record
112 *  returns:  nothing
113 *-----------------------------------------------------------------------*/
114#define CRTCSET(r) pPriv->reg->crtc.r = pPriv->x68kreg.crtc.r
115#define VIDEOCSET(r) pPriv->reg->videoc.r = pPriv->x68kreg.videoc.r
116
117static void
118x68kRegSetup(X68kScreenRec *pPriv)
119{
120    u_short pr20 = pPriv->reg->crtc.r20;
121
122    /* timing registers */
123    if ( (pr20 & 0x0003) < (pPriv->x68kreg.crtc.r20 & 0x0003) ||
124         ( (pr20 & 0x0003) == (pPriv->x68kreg.crtc.r20 & 0x0003) &&
125           (pr20 & 0x0010) < (pPriv->x68kreg.crtc.r20 & 0x0010) ) ) {
126
127        /* to higher resolution */
128        CRTCSET(r00); CRTCSET(r01); CRTCSET(r02);CRTCSET(r03);
129        CRTCSET(r04); CRTCSET(r05); CRTCSET(r06);CRTCSET(r07);
130        CRTCSET(r20);
131    } else {
132        /* to lower resolution */
133        CRTCSET(r20); CRTCSET(r01); CRTCSET(r02);CRTCSET(r03);
134        CRTCSET(r04); CRTCSET(r05); CRTCSET(r06);CRTCSET(r07);
135        CRTCSET(r00);
136    }
137    CRTCSET(r08);
138
139    /* scroll registers */
140    CRTCSET(r12); CRTCSET(r13); CRTCSET(r14);CRTCSET(r15);
141    CRTCSET(r16); CRTCSET(r17); CRTCSET(r18);CRTCSET(r19);
142
143    /* mode controlling registers */
144    VIDEOCSET(r0); VIDEOCSET(r1); VIDEOCSET(r2);
145
146    /* dot clock bit */
147    pPriv->reg->sysport.r4 = (pPriv->x68kreg.dotClock)? 0x000e: 0x000c;
148}
149
150/*-------------------------------------------------------------------------
151 * function "x68kSaveScreen"                      [ screen function ]
152 *
153 *  purpose:  activate/deactivate screen saver
154 *  argument: (ScreenPtr)ipScreen : target screen to save
155 *            (int)mode          : on/off
156 *  returns:  nothing
157 *-----------------------------------------------------------------------*/
158Bool
159x68kSaveScreen(ScreenPtr pScreen, Bool on)
160{
161    X68kScreenRec *pPriv = x68kGetScreenPrivate(pScreen);
162    static int status = FALSE;
163    static u_short r2;
164
165    if (on == SCREEN_SAVER_ON || on == SCREEN_SAVER_CYCLE) {
166        if (!status) {
167            r2 = pPriv->reg->videoc.r2;
168            pPriv->reg->videoc.r2 = 0x0000;
169            status = TRUE;
170        }
171    } else {
172        if (status) {
173            pPriv->reg->videoc.r2 = r2;
174            status = FALSE;
175        }
176    }
177    return TRUE;
178}
179
180/* EOF x68kFb.c */
181