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