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