184d30d9dStsutsui/* $NetBSD: x68kFb.c,v 1.4 2020/11/05 16:06:08 tsutsui Exp $ */
2706f2543Smrg/*-------------------------------------------------------------------------
3706f2543Smrg * Copyright (c) 1996 Yasushi Yamasaki
4706f2543Smrg * All rights reserved.
5706f2543Smrg *
6706f2543Smrg * Redistribution and use in source and binary forms, with or without
7706f2543Smrg * modification, are permitted provided that the following conditions
8706f2543Smrg * are met:
9706f2543Smrg * 1. Redistributions of source code must retain the above copyright
10706f2543Smrg *    notice, this list of conditions and the following disclaimer.
11706f2543Smrg * 2. Redistributions in binary form must reproduce the above copyright
12706f2543Smrg *    notice, this list of conditions and the following disclaimer in the
13706f2543Smrg *    documentation and/or other materials provided with the distribution.
14706f2543Smrg *
15706f2543Smrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16706f2543Smrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17706f2543Smrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18706f2543Smrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19706f2543Smrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20706f2543Smrg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21706f2543Smrg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22706f2543Smrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23706f2543Smrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24706f2543Smrg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25706f2543Smrg *-----------------------------------------------------------------------*/
26706f2543Smrg
27706f2543Smrg#include "x68k.h"
28706f2543Smrg
29706f2543Smrgstatic void x68kRegSetup(X68kScreenRec *pPriv);
30706f2543Smrg
31706f2543SmrgDevPrivateKeyRec x68kScreenPrivateKeyRec;
32706f2543Smrg
3384d30d9dStsutsuistatic int cons_dwidth;
3484d30d9dStsutsui
35706f2543Smrg/*-------------------------------------------------------------------------
36706f2543Smrg * function "x68kFbCommonOpen"
37706f2543Smrg *
38706f2543Smrg *  purpose:  open and map frame buffer, and obtain some FB-specific
39706f2543Smrg *            infomation. then set controller to approppriate mode as
40ab290810Stsutsui *            configured in X68kConfig.
41706f2543Smrg *  argument: (X68kScreenRec *)pPriv : X68k private screen record
42706f2543Smrg *            (const char *)device   : name of frame buffer device
43706f2543Smrg *  returns:  (Bool): TRUE  if succeeded
44706f2543Smrg *                    FALSE otherwise
45706f2543Smrg *-----------------------------------------------------------------------*/
46706f2543SmrgBool
47706f2543Smrgx68kFbCommonOpen(X68kScreenRec *pPriv, const char *device)
48706f2543Smrg{
49706f2543Smrg    struct grfinfo gi;
50ab290810Stsutsui
51706f2543Smrg    /* open frame buffer */
52706f2543Smrg    if ( ( pPriv->fd = open(device, O_RDWR, 0)) < 0) {
53706f2543Smrg        Error( "Can't open frame buffer" );
54706f2543Smrg        return FALSE;
55706f2543Smrg    }
56706f2543Smrg    /* get frame buffer infomation */
57706f2543Smrg    if ( ioctl( pPriv->fd, GRFIOCGINFO, &gi ) == -1 ) {
58706f2543Smrg        Error( "Can't get grfinfo" );
59706f2543Smrg        return FALSE;
60706f2543Smrg    }
61706f2543Smrg    pPriv->mapsize = gi.gd_regsize + gi.gd_fbsize;
62ab290810Stsutsui
63706f2543Smrg    /* map control registers and frame buffer */
64706f2543Smrg    pPriv->reg = (FbReg *)mmap(0, pPriv->mapsize, PROT_READ | PROT_WRITE,
65706f2543Smrg                               MAP_FILE | MAP_SHARED, pPriv->fd, 0 );
66706f2543Smrg    if ( pPriv->reg == (FbReg *)-1) {
67706f2543Smrg        Error( "Can't map frame buffer" );
68706f2543Smrg        return FALSE;
69706f2543Smrg    }
70706f2543Smrg    pPriv->fb = (uint8_t *)((uint32_t)pPriv->reg + gi.gd_regsize);
71706f2543Smrg
72706f2543Smrg    x68kRegSetup( pPriv );
7384d30d9dStsutsui    cons_dwidth = gi.gd_dwidth;
74706f2543Smrg
75706f2543Smrg    return TRUE;
76706f2543Smrg}
77706f2543Smrg
78706f2543Smrg/*-------------------------------------------------------------------------
79706f2543Smrg * function "x68kFbCommonClose"
80706f2543Smrg *
81706f2543Smrg *  purpose:  unmap and close frame buffer, and
82706f2543Smrg *            change video mode to normal ITE mode
83706f2543Smrg *  argument: (X68kScreenRec *)pPriv : X68k private screen record
84706f2543Smrg *  returns:  nothing
85706f2543Smrg *-----------------------------------------------------------------------*/
86706f2543Smrgvoid
87706f2543Smrgx68kFbCommonClose(X68kScreenRec *pPriv)
88706f2543Smrg{
8984d30d9dStsutsui    static const X68kFbReg graphNone_mode16 = {
9084d30d9dStsutsui	/* CRT mode 16 (768x512 31.5kHz) */
91706f2543Smrg        { 137,14, 28, 124,
92706f2543Smrg          567, 5, 40, 552,
93706f2543Smrg           27, 0,  0,   0,
94706f2543Smrg            0, 0,  0,   0,
95706f2543Smrg            0, 0,  0,   0,
96706f2543Smrg       0x0416, 0,  0,   0, 0 },
97706f2543Smrg        { 0x0004, 0x21e4, 0x0020 },
98706f2543Smrg        0
99706f2543Smrg    };
10084d30d9dStsutsui    static const X68kFbReg graphNone_mode19 = {
10184d30d9dStsutsui	/* CRT mode 19 (640x480 31.5kHz VGA mode) */
10284d30d9dStsutsui        {  99,11, 13,  93,
10384d30d9dStsutsui          524, 1, 33, 513,
10484d30d9dStsutsui           27, 0,  0,   0,
10584d30d9dStsutsui            0, 0,  0,   0,
10684d30d9dStsutsui            0, 0,  0,   0,
10784d30d9dStsutsui       0x0417, 0,  0,   0, 0 },
10884d30d9dStsutsui        { 0x0004, 0x21e4, 0x0020 },
10984d30d9dStsutsui        0
11084d30d9dStsutsui    };
111706f2543Smrg    /* change video mode */
11284d30d9dStsutsui    pPriv->x68kreg = (cons_dwidth == 640) ? graphNone_mode19 : graphNone_mode16;
113706f2543Smrg    x68kRegSetup(pPriv);
114ab290810Stsutsui
115706f2543Smrg    /* unmap and close frame buffer */
11684d30d9dStsutsui    if ( munmap(pPriv->reg, pPriv->mapsize) == -1 )
117706f2543Smrg        Error("Can't unmap frame buffer");
118706f2543Smrg    close(pPriv->fd);
119706f2543Smrg}
120706f2543Smrg
121706f2543Smrg/*-------------------------------------------------------------------------
122706f2543Smrg * function "x68kRegSetup"
123706f2543Smrg *
124706f2543Smrg *  purpose:  set up CRT controller and Video controller
125706f2543Smrg *            with register values in pPriv->x68kreg
126706f2543Smrg *  argument: (X68kScreenRec *)pPriv : X68k private screen record
127706f2543Smrg *  returns:  nothing
128706f2543Smrg *-----------------------------------------------------------------------*/
129706f2543Smrg#define CRTCSET(r) pPriv->reg->crtc.r = pPriv->x68kreg.crtc.r
130706f2543Smrg#define VIDEOCSET(r) pPriv->reg->videoc.r = pPriv->x68kreg.videoc.r
131706f2543Smrg
132706f2543Smrgstatic void
133706f2543Smrgx68kRegSetup(X68kScreenRec *pPriv)
134706f2543Smrg{
13584d30d9dStsutsui    uint16_t pr20 = pPriv->reg->crtc.r20;
136706f2543Smrg
137706f2543Smrg    /* timing registers */
138706f2543Smrg    if ( (pr20 & 0x0003) < (pPriv->x68kreg.crtc.r20 & 0x0003) ||
139706f2543Smrg         ( (pr20 & 0x0003) == (pPriv->x68kreg.crtc.r20 & 0x0003) &&
140706f2543Smrg           (pr20 & 0x0010) < (pPriv->x68kreg.crtc.r20 & 0x0010) ) ) {
141ab290810Stsutsui
142706f2543Smrg        /* to higher resolution */
143706f2543Smrg        CRTCSET(r00); CRTCSET(r01); CRTCSET(r02);CRTCSET(r03);
144706f2543Smrg        CRTCSET(r04); CRTCSET(r05); CRTCSET(r06);CRTCSET(r07);
145706f2543Smrg        CRTCSET(r20);
146706f2543Smrg    } else {
147706f2543Smrg        /* to lower resolution */
148706f2543Smrg        CRTCSET(r20); CRTCSET(r01); CRTCSET(r02);CRTCSET(r03);
149706f2543Smrg        CRTCSET(r04); CRTCSET(r05); CRTCSET(r06);CRTCSET(r07);
150706f2543Smrg        CRTCSET(r00);
151706f2543Smrg    }
152706f2543Smrg    CRTCSET(r08);
153706f2543Smrg
154706f2543Smrg    /* scroll registers */
155706f2543Smrg    CRTCSET(r12); CRTCSET(r13); CRTCSET(r14);CRTCSET(r15);
156706f2543Smrg    CRTCSET(r16); CRTCSET(r17); CRTCSET(r18);CRTCSET(r19);
157706f2543Smrg
158706f2543Smrg    /* mode controlling registers */
159706f2543Smrg    VIDEOCSET(r0); VIDEOCSET(r1); VIDEOCSET(r2);
160706f2543Smrg
161706f2543Smrg    /* dot clock bit */
162706f2543Smrg    pPriv->reg->sysport.r4 = (pPriv->x68kreg.dotClock)? 0x000e: 0x000c;
163706f2543Smrg}
164706f2543Smrg
165706f2543Smrg/*-------------------------------------------------------------------------
166706f2543Smrg * function "x68kSaveScreen"                      [ screen function ]
167706f2543Smrg *
168706f2543Smrg *  purpose:  activate/deactivate screen saver
169706f2543Smrg *  argument: (ScreenPtr)ipScreen : target screen to save
170706f2543Smrg *            (int)mode          : on/off
171706f2543Smrg *  returns:  nothing
172706f2543Smrg *-----------------------------------------------------------------------*/
173706f2543SmrgBool
174706f2543Smrgx68kSaveScreen(ScreenPtr pScreen, Bool on)
175706f2543Smrg{
176706f2543Smrg    X68kScreenRec *pPriv = x68kGetScreenPrivate(pScreen);
177706f2543Smrg    static int status = FALSE;
17884d30d9dStsutsui    static uint16_t r2;
179706f2543Smrg
180706f2543Smrg    if (on == SCREEN_SAVER_ON || on == SCREEN_SAVER_CYCLE) {
181706f2543Smrg        if (!status) {
182706f2543Smrg            r2 = pPriv->reg->videoc.r2;
183706f2543Smrg            pPriv->reg->videoc.r2 = 0x0000;
184706f2543Smrg            status = TRUE;
185706f2543Smrg        }
186706f2543Smrg    } else {
187706f2543Smrg        if (status) {
188706f2543Smrg            pPriv->reg->videoc.r2 = r2;
189706f2543Smrg            status = FALSE;
190706f2543Smrg        }
191706f2543Smrg    }
192706f2543Smrg    return TRUE;
193706f2543Smrg}
194706f2543Smrg
195706f2543Smrg/* EOF x68kFb.c */
196