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