x68kFb.c revision 84d30d9d
1/* $NetBSD: x68kFb.c,v 1.4 2020/11/05 16:06:08 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
33static int cons_dwidth;
34
35/*-------------------------------------------------------------------------
36 * function "x68kFbCommonOpen"
37 *
38 *  purpose:  open and map frame buffer, and obtain some FB-specific
39 *            infomation. then set controller to approppriate mode as
40 *            configured in X68kConfig.
41 *  argument: (X68kScreenRec *)pPriv : X68k private screen record
42 *            (const char *)device   : name of frame buffer device
43 *  returns:  (Bool): TRUE  if succeeded
44 *                    FALSE otherwise
45 *-----------------------------------------------------------------------*/
46Bool
47x68kFbCommonOpen(X68kScreenRec *pPriv, const char *device)
48{
49    struct grfinfo gi;
50
51    /* open frame buffer */
52    if ( ( pPriv->fd = open(device, O_RDWR, 0)) < 0) {
53        Error( "Can't open frame buffer" );
54        return FALSE;
55    }
56    /* get frame buffer infomation */
57    if ( ioctl( pPriv->fd, GRFIOCGINFO, &gi ) == -1 ) {
58        Error( "Can't get grfinfo" );
59        return FALSE;
60    }
61    pPriv->mapsize = gi.gd_regsize + gi.gd_fbsize;
62
63    /* map control registers and frame buffer */
64    pPriv->reg = (FbReg *)mmap(0, pPriv->mapsize, PROT_READ | PROT_WRITE,
65                               MAP_FILE | MAP_SHARED, pPriv->fd, 0 );
66    if ( pPriv->reg == (FbReg *)-1) {
67        Error( "Can't map frame buffer" );
68        return FALSE;
69    }
70    pPriv->fb = (uint8_t *)((uint32_t)pPriv->reg + gi.gd_regsize);
71
72    x68kRegSetup( pPriv );
73    cons_dwidth = gi.gd_dwidth;
74
75    return TRUE;
76}
77
78/*-------------------------------------------------------------------------
79 * function "x68kFbCommonClose"
80 *
81 *  purpose:  unmap and close frame buffer, and
82 *            change video mode to normal ITE mode
83 *  argument: (X68kScreenRec *)pPriv : X68k private screen record
84 *  returns:  nothing
85 *-----------------------------------------------------------------------*/
86void
87x68kFbCommonClose(X68kScreenRec *pPriv)
88{
89    static const X68kFbReg graphNone_mode16 = {
90	/* CRT mode 16 (768x512 31.5kHz) */
91        { 137,14, 28, 124,
92          567, 5, 40, 552,
93           27, 0,  0,   0,
94            0, 0,  0,   0,
95            0, 0,  0,   0,
96       0x0416, 0,  0,   0, 0 },
97        { 0x0004, 0x21e4, 0x0020 },
98        0
99    };
100    static const X68kFbReg graphNone_mode19 = {
101	/* CRT mode 19 (640x480 31.5kHz VGA mode) */
102        {  99,11, 13,  93,
103          524, 1, 33, 513,
104           27, 0,  0,   0,
105            0, 0,  0,   0,
106            0, 0,  0,   0,
107       0x0417, 0,  0,   0, 0 },
108        { 0x0004, 0x21e4, 0x0020 },
109        0
110    };
111    /* change video mode */
112    pPriv->x68kreg = (cons_dwidth == 640) ? graphNone_mode19 : graphNone_mode16;
113    x68kRegSetup(pPriv);
114
115    /* unmap and close frame buffer */
116    if ( munmap(pPriv->reg, pPriv->mapsize) == -1 )
117        Error("Can't unmap frame buffer");
118    close(pPriv->fd);
119}
120
121/*-------------------------------------------------------------------------
122 * function "x68kRegSetup"
123 *
124 *  purpose:  set up CRT controller and Video controller
125 *            with register values in pPriv->x68kreg
126 *  argument: (X68kScreenRec *)pPriv : X68k private screen record
127 *  returns:  nothing
128 *-----------------------------------------------------------------------*/
129#define CRTCSET(r) pPriv->reg->crtc.r = pPriv->x68kreg.crtc.r
130#define VIDEOCSET(r) pPriv->reg->videoc.r = pPriv->x68kreg.videoc.r
131
132static void
133x68kRegSetup(X68kScreenRec *pPriv)
134{
135    uint16_t pr20 = pPriv->reg->crtc.r20;
136
137    /* timing registers */
138    if ( (pr20 & 0x0003) < (pPriv->x68kreg.crtc.r20 & 0x0003) ||
139         ( (pr20 & 0x0003) == (pPriv->x68kreg.crtc.r20 & 0x0003) &&
140           (pr20 & 0x0010) < (pPriv->x68kreg.crtc.r20 & 0x0010) ) ) {
141
142        /* to higher resolution */
143        CRTCSET(r00); CRTCSET(r01); CRTCSET(r02);CRTCSET(r03);
144        CRTCSET(r04); CRTCSET(r05); CRTCSET(r06);CRTCSET(r07);
145        CRTCSET(r20);
146    } else {
147        /* to lower resolution */
148        CRTCSET(r20); CRTCSET(r01); CRTCSET(r02);CRTCSET(r03);
149        CRTCSET(r04); CRTCSET(r05); CRTCSET(r06);CRTCSET(r07);
150        CRTCSET(r00);
151    }
152    CRTCSET(r08);
153
154    /* scroll registers */
155    CRTCSET(r12); CRTCSET(r13); CRTCSET(r14);CRTCSET(r15);
156    CRTCSET(r16); CRTCSET(r17); CRTCSET(r18);CRTCSET(r19);
157
158    /* mode controlling registers */
159    VIDEOCSET(r0); VIDEOCSET(r1); VIDEOCSET(r2);
160
161    /* dot clock bit */
162    pPriv->reg->sysport.r4 = (pPriv->x68kreg.dotClock)? 0x000e: 0x000c;
163}
164
165/*-------------------------------------------------------------------------
166 * function "x68kSaveScreen"                      [ screen function ]
167 *
168 *  purpose:  activate/deactivate screen saver
169 *  argument: (ScreenPtr)ipScreen : target screen to save
170 *            (int)mode          : on/off
171 *  returns:  nothing
172 *-----------------------------------------------------------------------*/
173Bool
174x68kSaveScreen(ScreenPtr pScreen, Bool on)
175{
176    X68kScreenRec *pPriv = x68kGetScreenPrivate(pScreen);
177    static int status = FALSE;
178    static uint16_t r2;
179
180    if (on == SCREEN_SAVER_ON || on == SCREEN_SAVER_CYCLE) {
181        if (!status) {
182            r2 = pPriv->reg->videoc.r2;
183            pPriv->reg->videoc.r2 = 0x0000;
184            status = TRUE;
185        }
186    } else {
187        if (status) {
188            pPriv->reg->videoc.r2 = r2;
189            status = FALSE;
190        }
191    }
192    return TRUE;
193}
194
195/* EOF x68kFb.c */
196