/* ------------------------------------------------------------------------- saturn - A poor-man's emulator of some HP calculators Copyright (C) 1998-2000 Ivan Cibrario Bertolotti This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the documentation of this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. For more information, please contact the author, preferably by email, at the following address: Ivan Cibrario Bertolotti IRITI - National Research Council c/o IEN "Galileo Ferraris" Strada delle Cacce, 91 10135 - Torino (ITALY) email: cibrario@iriti.cnr.it ------------------------------------------------------------------------- */ /* +-+ */ /* .+ .identifier : $Id: display.c,v 4.1.1.1 2002/11/11 16:12:46 cibrario Exp $ .context : SATURN, Saturn CPU / HP48 emulator .title : $RCSfile: display.c,v $ .kind : C source .author : Ivan Cibrario B. .site : CSTV-CNR .creation : 29-Jan-1998 .keywords : * .description : This source module emulates the Lcd driver of the Yorke chip. References: SASM.DOC by HP (HORN disk 4) Guide to the Saturn Processor Rev. 0.00f by Matthew Mastracci entries.srt by Mika Heiskanen (mheiskan@vipunen.hut.fi) x48 source code by Eddie C. Dost (ecd@dressler.de) NOTE: In the current (r1.1) implementation, the control fields mod_status.hdw.lcd_offset and mod_status.hdw.lcd_contrast are not supported. Therefore, the emulation accuracy is sometimes poor; for example, the Equation Writer does not work well with large equations. .include : config.h, machdep.h, cpu.h, modules.h, display.h .notes : $Log: display.c,v $ Revision 4.1.1.1 2002/11/11 16:12:46 cibrario Small screen support; preliminary Revision 4.1 2000/12/11 09:54:19 cibrario Public release. Revision 3.10 2000/10/24 16:14:37 cibrario Added/Replaced GPL header Revision 3.8 2000/10/23 13:15:36 cibrario Bug fix: In InitLcd(), added a clip rectangle to GC, to avoid drawing non-existent pixels, that is, pixels that *do* exist in the frame buffer, but should never be viewed on screen. Revision 3.5 2000/10/02 09:44:42 cibrario Linux support: - gcc does not like array subscripts with type 'char', and it is right. Revision 3.1 2000/09/20 13:47:58 cibrario Minor updates and fixes to avoid gcc compiler warnings on Solaris when -ansi -pedantic -Wall options are selected. * Revision 1.1 1998/02/17 14:14:39 cibrario * Initial revision * .- */ #ifndef lint static char rcs_id[] = "$Id: display.c,v 4.1.1.1 2002/11/11 16:12:46 cibrario Exp $"; #endif #include #include #include #include /* 3.1: memset() */ #include #include "config.h" #include "machdep.h" #include "cpu.h" #include "modules.h" #include "display.h" #include "x11.h" #include "debug.h" #define CHF_MODULE_ID X11_CHF_MODULE_ID #include #ifndef LCD_MAG # define LCD_MAG 2 /* 4.1.1.1: Compat. default */ #endif #define NIBBLES_PER_ROW 34 /* 136 pixel total */ #define MAX_ROWS 64 /* 64 rows total */ #define N_ANN 6 /* # of annunciators */ #define LCD_X_ORIGIN 1+4*(LCD_MAG-1) /* x origin */ #if LCD_MAG==1 # define LCD_Y_ORIGIN 14 /* y origin */ #else # define LCD_Y_ORIGIN 20 /* y origin */ #endif /* 3.8: Origin and size of clip rectangle */ #define LCD_CLIP_X_ORIGIN LCD_X_ORIGIN #define LCD_CLIP_Y_ORIGIN 0 /* Don't clip annunciators */ #define LCD_CLIP_WIDTH 131*LCD_MAG #define LCD_CLIP_HEIGHT LCD_Y_ORIGIN+64*LCD_MAG #define MASK_ANN_LEFT 0x81 /* Annunciator's bit masks */ #define MASK_ANN_RIGHT 0x82 #define MASK_ANN_ALPHA 0x84 #define MASK_ANN_BATTERY 0x88 #define MASK_ANN_BUSY 0x90 #define MASK_ANN_IO 0xA0 /*--------------------------------------------------------------------------- Static/Global variables ---------------------------------------------------------------------------*/ static /*const*/ char nibble_bitmap_data[NIBBLE_VALUES][LCD_MAG] = { #if LCD_MAG==1 { 0x00 }, /* ---- */ { 0x01 }, /* *--- */ { 0x02 }, /* -*-- */ { 0x03 }, /* **-- */ { 0x04 }, /* --*- */ { 0x05 }, /* *-*- */ { 0x06 }, /* -**- */ { 0x07 }, /* ***- */ { 0x08 }, /* ---* */ { 0x09 }, /* *--* */ { 0x0a }, /* -*-* */ { 0x0b }, /* **-* */ { 0x0c }, /* --** */ { 0x0d }, /* *-** */ { 0x0e }, /* -*** */ { 0x0f } /* **** */ #elif LCD_MAG==2 { 0x00, 0x00 }, /* ---- */ { 0x03, 0x03 }, /* *--- */ { 0x0c, 0x0c }, /* -*-- */ { 0x0f, 0x0f }, /* **-- */ { 0x30, 0x30 }, /* --*- */ { 0x33, 0x33 }, /* *-*- */ { 0x3c, 0x3c }, /* -**- */ { 0x3f, 0x3f }, /* ***- */ { 0xc0, 0xc0 }, /* ---* */ { 0xc3, 0xc3 }, /* *--* */ { 0xcc, 0xcc }, /* -*-* */ { 0xcf, 0xcf }, /* **-* */ { 0xf0, 0xf0 }, /* --** */ { 0xf3, 0xf3 }, /* *-** */ { 0xfc, 0xfc }, /* -*** */ { 0xff, 0xff } /* **** */ #else # error "Bad LCD_MAG; supported values are 1 and 2" #endif }; static /*const*/ struct { int mask; /* Bit mask */ int x, y; /* Position */ int w, h; /* Width, Height */ char bitmap_data[24]; /* Bitmap data */ } #define ANN_X(i) (8*LCD_MAG+(22*LCD_MAG+1)*i) #define ANN_Y(i) (1+3*(LCD_MAG-1)) ann_data[N_ANN] = { { MASK_ANN_LEFT, ANN_X(0), ANN_Y(0), 15, 12, { 0xfe, 0x3f, 0xff, 0x7f, 0x9f, 0x7f, 0xcf, 0x7f, 0xe7, 0x7f, 0x03, 0x78, 0x03, 0x70, 0xe7, 0x73, 0xcf, 0x73, 0x9f, 0x73, 0xff, 0x73, 0xfe, 0x33 } }, { MASK_ANN_RIGHT, ANN_X(1), ANN_Y(1), 15, 12, { 0xfe, 0x3f, 0xff, 0x7f, 0xff, 0x7c, 0xff, 0x79, 0xff, 0x73, 0x0f, 0x60, 0x07, 0x60, 0xe7, 0x73, 0xe7, 0x79, 0xe7, 0x7c, 0xe7, 0x7f, 0xe6, 0x3f } }, { MASK_ANN_ALPHA, ANN_X(2), ANN_Y(2), 15, 12, { 0xe0, 0x03, 0x18, 0x44, 0x0c, 0x4c, 0x06, 0x2c, 0x07, 0x2c, 0x07, 0x1c, 0x07, 0x0c, 0x07, 0x0c, 0x07, 0x0e, 0x0e, 0x4d, 0xf8, 0x38, 0x00, 0x00 } }, { MASK_ANN_BATTERY, ANN_X(3), ANN_Y(3), 15, 12, { 0x04, 0x10, 0x02, 0x20, 0x12, 0x24, 0x09, 0x48, 0xc9, 0x49, 0xc9, 0x49, 0xc9, 0x49, 0x09, 0x48, 0x12, 0x24, 0x02, 0x20, 0x04, 0x10, 0x00, 0x00 } }, { MASK_ANN_BUSY, ANN_X(4), ANN_Y(4), 15, 12, { 0xfc, 0x1f, 0x08, 0x08, 0x08, 0x08, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0x40, 0x01, 0x20, 0x02, 0x10, 0x04, 0xc8, 0x09, 0xe8, 0x0b, 0xfc, 0x1f } }, { MASK_ANN_IO, ANN_X(5), ANN_Y(5), 15, 12, { 0x0c, 0x00, 0x1e, 0x00, 0x33, 0x0c, 0x61, 0x18, 0xcc, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0xcc, 0x30, 0x61, 0x18, 0x33, 0x0c, 0x1e, 0x00, 0x0c, 0x00 } } }; static Nibble lcd_buffer[MAX_ROWS][NIBBLES_PER_ROW]; static int ann_buffer; static int clean; static Display *display; static Window window; static GC gc; static unsigned long fg_pixel, bg_pixel; static unsigned int depth; static Pixmap nibble_pixmap[NIBBLE_VALUES]; static Pixmap ann_pixmap[N_ANN]; /*--------------------------------------------------------------------------- Private functions ---------------------------------------------------------------------------*/ /* .+ .title : InitPixmaps .kind : C function .creation : 29-Jan-1998 .description : This function initializes the pixmaps for the Lcd screen elements and stores them into the appropriate global variables. .call : InitPixmaps(); .input : void .output : void .status_codes : X11_I_CALLED X11_F_X_ERROR .notes : 1.1, 29-Jan-1998, creation .- */ static void InitPixmaps(void) { int i; debug1(DEBUG_C_TRACE, X11_I_CALLED, "InitPixmaps"); /* Initialize nibble_pixmap */ for(i=0; i