/* ------------------------------------------------------------------------- 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: x_func.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $ .context : SATURN, Saturn CPU / HPxx emulator .title : $RCSfile: x_func.c,v $ .kind : C source .author : Ivan Cibrario B. .site : CSTV-CNR .creation : 3-Nov-2000 .keywords : * .description : This module implements the emulator's extended functions, that is, functions that the real machine has not. References: Private communications with Prof. B. Parisse .include : config.h, machdep.h, cpu.h, x_func.h .notes : $Log: x_func.c,v $ Revision 4.1 2000/12/11 09:54:19 cibrario Public release. Revision 3.15 2000/11/15 14:16:45 cibrario GUI enhancements and assorted bug fixes: - Implemented command-line option -batchXfer Revision 3.14 2000/11/13 11:11:01 cibrario Implemented fast load/save; improved keyboard interface emulation at high emulated CPU speed: - Added credits in file doc - Implemented CPU status access functions ByteFromAddress(), NameFromD1() - Implemented new static function BinaryHeader(), to select an header of binary files appropriate for the current hw configuration - Implemented new static functions Kget()/KgetContinuation(), to load a file from disk into the calculator, and Send/SendContinuation(), to save a file from the calculator's memory into a disk file. - Removed test functions TestFSB() and TestFSBContinuation() - Implemented static helper function SetupXfer(), to setup a disk transfer. - Updated static function[] table Revision 3.13 2000/11/09 11:42:22 cibrario *** empty log message *** .- */ #ifndef lint static char rcs_id[] = "$Id: x_func.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $"; #endif #include #include #include #include #include #include #include /* Main X header */ #include /* Main Xt header */ #include "config.h" #include "machdep.h" #include "cpu.h" #include "modules.h" #include "disk_io.h" #include "x11.h" /* ActivateFSB() */ #include "x_func.h" #include "args.h" #include "debug.h" #define CHF_MODULE_ID X_FUNC_CHF_MODULE_ID #include /*--------------------------------------------------------------------------- Private functions: CPU access ---------------------------------------------------------------------------*/ /* Return the A field of a DataRegister as an integer. */ static int R2int(const Nibble *r) { return( ((int)r[0] ) | ((int)r[1] << 4) | ((int)r[2] << 8) | ((int)r[3] << 12) | ((int)r[4] << 16) ); } /* Return the contents of the byte pointed by addr. Memory is accessed through ReadNibble() */ static int ByteFromAddress(Address addr) { return (int)ReadNibble(addr) + (int)ReadNibble(addr+1) * 16; } /* Return a dynamically-allocated copy of the contents of the IDNT object pointed by D1. D1 points to the *body* of the RPL object, that is, to the IDNT length byte directly and *not* to the prologue. */ static char *NameFromD1(void) { Address addr = cpu_status.D1; /* Points to the IDNT body */ int len = ByteFromAddress(addr); /* IDNT length */ char *name = XtMalloc(len+1); /* IDNT name buffer */ int c; /* Read the name; toascii() is there to avoid 'strange' characters */ for(c=0; c=0, has an architectural upper limit of 2^20, and int are at least 2^31. */ cpu_status.inner_loop_max = (new_speed * INNER_LOOP_MAX) / 4; /* Notify the user about the speed change */ if(cpu_status.inner_loop_max) ChfCondition X_FUNC_I_SET_SPEED, CHF_INFO, new_speed ChfEnd; else ChfCondition X_FUNC_I_MAX_SPEED, CHF_INFO ChfEnd; ChfSignal(); } #endif } /*---------------------------------------------------------------------------*/ /* This array holds the binary headers for all known hw configurations; here, '?' is a wildcard character when reading from file (see ReadObjectFromFile()) and is replaced by 'S' when writing to file (see WriteObjectToFile()). */ struct BinHdrMapping { char *hw; char *hdr; }; static const struct BinHdrMapping bin_hdr_mapping[] = { { "hp48", "HPHP48-?" }, { "hp49", "HPHP49-?" } }; #define N_BIN_HDR_MAPPING (sizeof(bin_hdr_mapping)/sizeof(bin_hdr_mapping[0])) /* Return the header of binary files for current hw configuration; return NULL if the header cannot be determined. In the latter case, generate an appropriate condition. */ static const char *BinaryHeader(void) { int i; for(i=0; i= N_X_FUNC || function[(int)function_code] == (XFunc)NULL) { ChfCondition X_FUNC_W_BAD_CODE, CHF_WARNING, function_code ChfEnd; ChfSignal(); } /* Dispatch */ else function[(int)function_code](function_code); }