copy .clang-format from x48ng and format all the code
This commit is contained in:
parent
18be3f70ba
commit
d085a1537e
56 changed files with 10264 additions and 11720 deletions
59
.clang-format
Normal file
59
.clang-format
Normal file
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
Language: Cpp
|
||||
ColumnLimit: 140
|
||||
IndentWidth: 4
|
||||
PPIndentWidth: 2
|
||||
UseTab: Never
|
||||
|
||||
AlignArrayOfStructures: Left
|
||||
|
||||
IndentCaseBlocks: true
|
||||
IndentCaseLabels: true
|
||||
IndentGotoLabels: false
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentWrappedFunctionNames: true
|
||||
|
||||
InsertBraces: false
|
||||
InsertNewlineAtEOF: true
|
||||
|
||||
MaxEmptyLinesToKeep: 1
|
||||
|
||||
PointerAlignment: Left
|
||||
ReferenceAlignment: Left
|
||||
QualifierAlignment: Left
|
||||
|
||||
SortIncludes: false
|
||||
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInAngles: true
|
||||
SpacesInCStyleCastParentheses: true
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInParentheses: true
|
||||
SpacesInSquareBrackets: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterExternBlock: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
...
|
2
Makefile
2
Makefile
|
@ -87,7 +87,7 @@ clean-all: mrproper
|
|||
|
||||
# Formatting
|
||||
pretty-code:
|
||||
clang-format -i src/*.c src/*.h
|
||||
clang-format -i src/*.c src/*.h src/libChf/*.c src/libChf/*.h
|
||||
|
||||
# Dependencies
|
||||
get-roms:
|
||||
|
|
32
src/args.h
32
src/args.h
|
@ -45,7 +45,7 @@
|
|||
This header declares a global data structure containing the emulator
|
||||
invocation arguments; this data structure is initialized before startup,
|
||||
either by means of argc/argv or in other ways.
|
||||
|
||||
|
||||
.include : config.h
|
||||
|
||||
.notes :
|
||||
|
@ -74,27 +74,25 @@
|
|||
.- */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Data type definitions - require config.h
|
||||
Data type definitions - require config.h
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
struct Args
|
||||
{
|
||||
int reset; /* 2.1: Force emulator reset */
|
||||
int monitor; /* 2.1: Call monitor() on startup */
|
||||
int batchXfer; /* 3.15: Non-interactive file transfers */
|
||||
char *mod_file_name;
|
||||
char *cpu_file_name;
|
||||
char *hdw_file_name;
|
||||
char *rom_file_name;
|
||||
char *ram_file_name;
|
||||
char *port_1_file_name;
|
||||
char *port_2_file_name;
|
||||
char *hw; /* 2.1: Hardware configuration (unused) */
|
||||
struct Args {
|
||||
int reset; /* 2.1: Force emulator reset */
|
||||
int monitor; /* 2.1: Call monitor() on startup */
|
||||
int batchXfer; /* 3.15: Non-interactive file transfers */
|
||||
char* mod_file_name;
|
||||
char* cpu_file_name;
|
||||
char* hdw_file_name;
|
||||
char* rom_file_name;
|
||||
char* ram_file_name;
|
||||
char* port_1_file_name;
|
||||
char* port_2_file_name;
|
||||
char* hw; /* 2.1: Hardware configuration (unused) */
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Global variables
|
||||
Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
extern struct Args args;
|
||||
|
|
48
src/config.h
48
src/config.h
|
@ -121,27 +121,24 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/* CHF_EXTENDED_INFO:
|
||||
Define this symbol if extended information is desired during condition
|
||||
handling; this is usually useful only for debugging purposes.
|
||||
*/
|
||||
/* #define CHF_EXTENDED_INFO */
|
||||
|
||||
|
||||
/* DEBUG:
|
||||
Define this symbol to include the debugging code for all source modules
|
||||
in the executable image.
|
||||
|
||||
|
||||
At run-time, the debug level can be set using the function SetDebugLevel();
|
||||
the initial debug level is set to the value of the symbol DEBUG_LEVEL,
|
||||
if it is defined, otherwise it is set to zero.
|
||||
*/
|
||||
/* #define DEBUG */
|
||||
|
||||
|
||||
/* DEBUG_LEVEL:
|
||||
When this symbol is defined and the debugging code has been included
|
||||
When this symbol is defined and the debugging code has been included
|
||||
in the executable image (DEBUG symbol set), the initial debug level
|
||||
is set to its value.
|
||||
|
||||
|
@ -149,8 +146,7 @@
|
|||
DEBUG_C_<> defined in debug.h; each of them corresponds to a class
|
||||
of debugging conditions that can be individually enabled or disabled.
|
||||
*/
|
||||
#define DEBUG_LEVEL DEBUG_C_REVISION
|
||||
|
||||
#define DEBUG_LEVEL DEBUG_C_REVISION
|
||||
|
||||
/* CPU_SPIN_SHUTDN
|
||||
If this symbol is defined, the cpu module implements the SHUTDN
|
||||
|
@ -176,7 +172,6 @@
|
|||
*/
|
||||
/* #define CPU_SPIN_SHUTDN */
|
||||
|
||||
|
||||
/* 2.1: FORCE_NONMODAL
|
||||
If this symbol is defined, nonmodal navigation is forced in the
|
||||
OSF/Motif GUI, by setting navigationType to XmNONE and traversalOn
|
||||
|
@ -184,15 +179,13 @@
|
|||
*/
|
||||
/* #define FORCE_NONMODAL */
|
||||
|
||||
|
||||
/* 2.4: N_PORT_2_BANK
|
||||
This symbol is used to dimension the HP48GX Port_2: it denotes the
|
||||
number of 128 Kbyte banks the port must have and must be a power of 2
|
||||
between 1 and 32, inclusive. When undefined, Port_2 is not emulated at all.
|
||||
The default value is 8, that is, Port_2 is emulated and its size is 1Mbyte.
|
||||
*/
|
||||
#define N_PORT_2_BANK 8
|
||||
|
||||
#define N_PORT_2_BANK 8
|
||||
|
||||
/* 2.5: SERIAL_FORCE_OPENPTY, SERIAL_FORCE_STREAMSPTY
|
||||
Optionally define exactly one of these symbols to force the use of a
|
||||
|
@ -203,7 +196,6 @@
|
|||
/* #define SERIAL_FORCE_OPENPTY */
|
||||
/* #define SERIAL_FORCE_STREAMSPTY */
|
||||
|
||||
|
||||
/* 3.2: HP49_SUPPORT
|
||||
Define this symbol to enable HP49-specific support code in the
|
||||
emulator; it does not harm if this symbol is defined when emulating
|
||||
|
@ -211,7 +203,6 @@
|
|||
*/
|
||||
#define HP49_SUPPORT
|
||||
|
||||
|
||||
/* 3.13: REAL_CPU_SPEED
|
||||
Define this symbol (recommended) to force the emulated CPU to run
|
||||
no faster than a software-controlled limit; by default, the limit
|
||||
|
@ -219,7 +210,6 @@
|
|||
*/
|
||||
#define REAL_CPU_SPEED
|
||||
|
||||
|
||||
/* 3.14: CPU_SLOW_IN
|
||||
Define this symbol (recommended) to slow down the A=IN and C=IN
|
||||
instructions depending on the current emulated CPU speed.
|
||||
|
@ -227,8 +217,7 @@
|
|||
The value of the macro determines the gain of the relation between
|
||||
CPU speed and slow down ratio.
|
||||
*/
|
||||
#define CPU_SLOW_IN 16
|
||||
|
||||
#define CPU_SLOW_IN 16
|
||||
|
||||
/* 4.1.1.1: LCD_MAG
|
||||
This symbol represents the magnification ratio of the emulated LCD pixels
|
||||
|
@ -236,32 +225,29 @@
|
|||
default. Currently, the value cannot be set at runtime for performance
|
||||
reasons.
|
||||
*/
|
||||
#define LCD_MAG 2
|
||||
|
||||
#define LCD_MAG 2
|
||||
|
||||
/* 4.1.1.1: When defined, this symbol represents the threshold of the long
|
||||
key pression. When the mouse button is kept pressed on a calculator's key
|
||||
for more than LONG_PRESS_THR milliseconds, the key stays pressed after
|
||||
release.
|
||||
*/
|
||||
#define LONG_PRESS_THR 1000
|
||||
|
||||
#define LONG_PRESS_THR 1000
|
||||
|
||||
/* Chf Module Identifiers:
|
||||
Each main module of the emulator has its own Chf Module Identifier; the
|
||||
values defined here must match those actually used in the message catalogs.
|
||||
*/
|
||||
#define MAIN_CHF_MODULE_ID 10
|
||||
#define CPU_CHF_MODULE_ID 11
|
||||
#define MOD_CHF_MODULE_ID 12
|
||||
#define DISK_IO_CHF_MODULE_ID 13
|
||||
#define X11_CHF_MODULE_ID 14
|
||||
#define SERIAL_CHF_MODULE_ID 15 /* 2.5 */
|
||||
#define FLASH_CHF_MODULE_ID 16 /* 3.3 */
|
||||
#define UTIL_CHF_MODULE_ID 17 /* 3.6 */
|
||||
#define X_FUNC_CHF_MODULE_ID 18 /* 3.13 */
|
||||
#define DEBUG_CHF_MODULE_ID 30
|
||||
|
||||
#define MAIN_CHF_MODULE_ID 10
|
||||
#define CPU_CHF_MODULE_ID 11
|
||||
#define MOD_CHF_MODULE_ID 12
|
||||
#define DISK_IO_CHF_MODULE_ID 13
|
||||
#define X11_CHF_MODULE_ID 14
|
||||
#define SERIAL_CHF_MODULE_ID 15 /* 2.5 */
|
||||
#define FLASH_CHF_MODULE_ID 16 /* 3.3 */
|
||||
#define UTIL_CHF_MODULE_ID 17 /* 3.6 */
|
||||
#define X_FUNC_CHF_MODULE_ID 18 /* 3.13 */
|
||||
#define DEBUG_CHF_MODULE_ID 30
|
||||
|
||||
/* 3.16: Include automatic exceptions to user configuration */
|
||||
#include "config_x.h"
|
||||
|
|
|
@ -58,8 +58,7 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/* REAL_CPU_SPEED is not supported on ultrix, because there is no usleep() */
|
||||
#ifdef ultrix
|
||||
#undef REAL_CPU_SPEED
|
||||
# undef REAL_CPU_SPEED
|
||||
#endif
|
||||
|
|
335
src/cpu.h
335
src/cpu.h
|
@ -67,8 +67,8 @@
|
|||
requests and emulator's extended functions:
|
||||
|
||||
- Added new fields:
|
||||
struct CpuStatus.halt (number of pending halt requests)
|
||||
struct CpuStatus.inner_loop_max (upper limit of inner_loop)
|
||||
struct CpuStatus.halt (number of pending halt requests)
|
||||
struct CpuStatus.inner_loop_max (upper limit of inner_loop)
|
||||
- New condition codes: CPU_I_HALT, CPU_I_RUN, CPU_E_NO_HALT
|
||||
- New prototypes: CpuHaltRequest(), CpuRunRequest(), CpuHaltAllowed()
|
||||
|
||||
|
@ -105,9 +105,8 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macro/Data type definitions - require machdep.h
|
||||
Macro/Data type definitions - require machdep.h
|
||||
|
||||
N_SCRATCH_REGISTER_ALL, used during scratch register space allocation
|
||||
is larger than necessary to avoid additional checks on the validity of
|
||||
|
@ -115,238 +114,224 @@
|
|||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* General */
|
||||
#define NIBBLE_PER_REGISTER 16
|
||||
#define N_WORKING_REGISTER 4
|
||||
#define N_SCRATCH_REGISTER 5
|
||||
#define N_SCRATCH_REGISTER_ALL 8
|
||||
#define N_DATA_POINTER_REGISTER 2
|
||||
#define RETURN_STACK_SIZE 8
|
||||
#define NIBBLE_VALUES 16
|
||||
#define NIBBLE_PER_REGISTER 16
|
||||
#define N_WORKING_REGISTER 4
|
||||
#define N_SCRATCH_REGISTER 5
|
||||
#define N_SCRATCH_REGISTER_ALL 8
|
||||
#define N_DATA_POINTER_REGISTER 2
|
||||
#define RETURN_STACK_SIZE 8
|
||||
#define NIBBLE_VALUES 16
|
||||
|
||||
#define INT_HANDLER_PC ((Address)0x0000F)
|
||||
#define INT_HANDLER_PC ( ( Address )0x0000F )
|
||||
|
||||
#define DISASSEMBLE_OB_SIZE 128
|
||||
#define DUMP_CPU_STATUS_OB_SIZE 512
|
||||
|
||||
#define CPU_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
#define DISASSEMBLE_OB_SIZE 128
|
||||
#define DUMP_CPU_STATUS_OB_SIZE 512
|
||||
|
||||
#define CPU_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
|
||||
/* Instruction opcode access macros:
|
||||
GetFS(f) returns the short field-selector value from the
|
||||
given nibble (bits 2..0)
|
||||
given nibble (bits 2..0)
|
||||
|
||||
GetImmFS(f) returns the immediate-field-selector flag from the
|
||||
given nibble (bit 3)
|
||||
=0: regular field selector
|
||||
!=0: immediate field selector
|
||||
given nibble (bit 3)
|
||||
=0: regular field selector
|
||||
!=0: immediate field selector
|
||||
|
||||
GetOC_1(o) returns the short operation code from the given
|
||||
nibble (bits 3..2 >>2)
|
||||
nibble (bits 3..2 >>2)
|
||||
|
||||
GetOC_2(f, o) returns the long operation code from the given
|
||||
nibbles (f bit 3, o bits 3..2)
|
||||
nibbles (f bit 3, o bits 3..2)
|
||||
|
||||
GetOC_3b(o) returns the long operation code from the given
|
||||
nibble (bits 2..0)
|
||||
nibble (bits 2..0)
|
||||
|
||||
GetRP(o) returns the register-pair identifier from the given
|
||||
nibble (bits 1..0)
|
||||
nibble (bits 1..0)
|
||||
|
||||
GetRn(r) returns the R register index from the given nibble
|
||||
(bits 2..0)
|
||||
(bits 2..0)
|
||||
|
||||
GetAC(r) returns the A/C register flag from the given nibble
|
||||
(bit 3)
|
||||
=0: register A
|
||||
!=0: register C
|
||||
(bit 3)
|
||||
=0: register A
|
||||
!=0: register C
|
||||
|
||||
GetAS(r) returns the add/subtract flag from the given nibble
|
||||
(bit 3)
|
||||
=0: add
|
||||
!=0: subtract
|
||||
*/
|
||||
#define GetFS(f) ((f) & 0x7)
|
||||
#define GetImmFS(o) ((o) & 0x8)
|
||||
#define GetOC_1(o) (((o) & 0xC)>>2)
|
||||
#define GetOC_2(f, o) ((((f) & 0x8)>>1) | (((o) & 0xC)>>2))
|
||||
#define GetOC_3b(o) ((o) & 0x7)
|
||||
#define GetRP(o) ((o) & 0x3)
|
||||
#define GetRn(r) ((r) & 0x7)
|
||||
#define GetAC(r) ((r) & 0x8)
|
||||
#define GetAS(r) ((r) & 0x8)
|
||||
|
||||
(bit 3)
|
||||
=0: add
|
||||
!=0: subtract
|
||||
*/
|
||||
#define GetFS( f ) ( ( f ) & 0x7 )
|
||||
#define GetImmFS( o ) ( ( o ) & 0x8 )
|
||||
#define GetOC_1( o ) ( ( ( o ) & 0xC ) >> 2 )
|
||||
#define GetOC_2( f, o ) ( ( ( ( f ) & 0x8 ) >> 1 ) | ( ( ( o ) & 0xC ) >> 2 ) )
|
||||
#define GetOC_3b( o ) ( ( o ) & 0x7 )
|
||||
#define GetRP( o ) ( ( o ) & 0x3 )
|
||||
#define GetRn( r ) ( ( r ) & 0x7 )
|
||||
#define GetAC( r ) ( ( r ) & 0x8 )
|
||||
#define GetAS( r ) ( ( r ) & 0x8 )
|
||||
|
||||
/* Field selector codes */
|
||||
#define FS_P 0
|
||||
#define FS_WP 1
|
||||
#define FS_XS 2
|
||||
#define FS_X 3
|
||||
#define FS_S 4
|
||||
#define FS_M 5
|
||||
#define FS_B 6
|
||||
#define FS_W 7
|
||||
#define FS_A 15
|
||||
#define N_FS 16 /* Total # of FS codes */
|
||||
|
||||
#define FS_P 0
|
||||
#define FS_WP 1
|
||||
#define FS_XS 2
|
||||
#define FS_X 3
|
||||
#define FS_S 4
|
||||
#define FS_M 5
|
||||
#define FS_B 6
|
||||
#define FS_W 7
|
||||
#define FS_A 15
|
||||
#define N_FS 16 /* Total # of FS codes */
|
||||
|
||||
/* Register pair codes */
|
||||
#define RP_AB 0
|
||||
#define RP_BC 1
|
||||
#define RP_CA 2
|
||||
#define RP_DC 3
|
||||
#define N_RP 4 /* Total # of RP codes */
|
||||
|
||||
#define RP_AB 0
|
||||
#define RP_BC 1
|
||||
#define RP_CA 2
|
||||
#define RP_DC 3
|
||||
#define N_RP 4 /* Total # of RP codes */
|
||||
|
||||
/* Masks */
|
||||
#define NIBBLE_MASK ((Nibble)0xF)
|
||||
#define ADDRESS_MASK ((Address)0xFFFFF)
|
||||
#define NIBBLE_MASK ( ( Nibble )0xF )
|
||||
#define ADDRESS_MASK ( ( Address )0xFFFFF )
|
||||
|
||||
#define CLRST_MASK ((ProgramStatusRegister)0xF000)
|
||||
#define D_S_MASK ((Address)0xF0000)
|
||||
#define RETURN_SP_MASK 0x7
|
||||
#define CLRST_MASK ( ( ProgramStatusRegister )0xF000 )
|
||||
#define D_S_MASK ( ( Address )0xF0000 )
|
||||
#define RETURN_SP_MASK 0x7
|
||||
|
||||
|
||||
typedef int1 Bit;
|
||||
typedef int4 Nibble;
|
||||
typedef int20 Address;
|
||||
typedef int12 OutputRegister;
|
||||
typedef int16 InputRegister;
|
||||
typedef int16 ProgramStatusRegister;
|
||||
typedef Nibble DataRegister[NIBBLE_PER_REGISTER];
|
||||
typedef int1 Bit;
|
||||
typedef int4 Nibble;
|
||||
typedef int20 Address;
|
||||
typedef int12 OutputRegister;
|
||||
typedef int16 InputRegister;
|
||||
typedef int16 ProgramStatusRegister;
|
||||
typedef Nibble DataRegister[ NIBBLE_PER_REGISTER ];
|
||||
|
||||
/* The XAddress data type holds extended addresses used to access Port 2 */
|
||||
typedef int32 XAddress;
|
||||
typedef int32 XAddress;
|
||||
|
||||
enum IntRequest
|
||||
{
|
||||
INT_REQUEST_NONE,
|
||||
INT_REQUEST_IRQ,
|
||||
INT_REQUEST_NMI
|
||||
};
|
||||
enum IntRequest { INT_REQUEST_NONE, INT_REQUEST_IRQ, INT_REQUEST_NMI };
|
||||
|
||||
struct CpuStatus
|
||||
{
|
||||
DataRegister work[N_WORKING_REGISTER];
|
||||
#define A work[0]
|
||||
#define B work[1]
|
||||
#define C work[2]
|
||||
#define D work[3]
|
||||
struct CpuStatus {
|
||||
DataRegister work[ N_WORKING_REGISTER ];
|
||||
#define A work[ 0 ]
|
||||
#define B work[ 1 ]
|
||||
#define C work[ 2 ]
|
||||
#define D work[ 3 ]
|
||||
|
||||
DataRegister R[N_SCRATCH_REGISTER_ALL];
|
||||
#define R0 R[0]
|
||||
#define R1 R[1]
|
||||
#define R2 R[2]
|
||||
#define R3 R[3]
|
||||
#define R4 R[4]
|
||||
DataRegister R[ N_SCRATCH_REGISTER_ALL ];
|
||||
#define R0 R[ 0 ]
|
||||
#define R1 R[ 1 ]
|
||||
#define R2 R[ 2 ]
|
||||
#define R3 R[ 3 ]
|
||||
#define R4 R[ 4 ]
|
||||
|
||||
Address DAT[N_DATA_POINTER_REGISTER];
|
||||
#define D0 DAT[0]
|
||||
#define D1 DAT[1]
|
||||
Address DAT[ N_DATA_POINTER_REGISTER ];
|
||||
#define D0 DAT[ 0 ]
|
||||
#define D1 DAT[ 1 ]
|
||||
|
||||
Nibble P;
|
||||
Address PC;
|
||||
InputRegister IN;
|
||||
OutputRegister OUT;
|
||||
ProgramStatusRegister ST;
|
||||
Nibble P;
|
||||
Address PC;
|
||||
InputRegister IN;
|
||||
OutputRegister OUT;
|
||||
ProgramStatusRegister ST;
|
||||
|
||||
Nibble HST;
|
||||
#define HST_MP_MASK 0x08
|
||||
#define HST_SR_MASK 0x04
|
||||
#define HST_SB_MASK 0x02
|
||||
#define HST_XM_MASK 0x01
|
||||
Nibble HST;
|
||||
#define HST_MP_MASK 0x08
|
||||
#define HST_SR_MASK 0x04
|
||||
#define HST_SB_MASK 0x02
|
||||
#define HST_XM_MASK 0x01
|
||||
|
||||
Address return_stack[RETURN_STACK_SIZE];
|
||||
int return_sp;
|
||||
Address return_stack[ RETURN_STACK_SIZE ];
|
||||
int return_sp;
|
||||
|
||||
int fs_idx_lo[N_FS];
|
||||
int fs_idx_hi[N_FS];
|
||||
int hexmode; /* DEC/HEX mode, 1=HEX */
|
||||
int carry; /* Carry bit 1=set */
|
||||
int shutdn; /* SHUTDN flag, 1=executed */
|
||||
int halt; /* 3.13: # of pending Halt */
|
||||
int int_enable; /* Int. enable, 1=enabled */
|
||||
int int_service; /* Int. service, 1=service */
|
||||
enum IntRequest int_pending; /* Pending interrupt request */
|
||||
int fs_idx_lo[ N_FS ];
|
||||
int fs_idx_hi[ N_FS ];
|
||||
int hexmode; /* DEC/HEX mode, 1=HEX */
|
||||
int carry; /* Carry bit 1=set */
|
||||
int shutdn; /* SHUTDN flag, 1=executed */
|
||||
int halt; /* 3.13: # of pending Halt */
|
||||
int int_enable; /* Int. enable, 1=enabled */
|
||||
int int_service; /* Int. service, 1=service */
|
||||
enum IntRequest int_pending; /* Pending interrupt request */
|
||||
|
||||
/* 3.13: inner_loop_max gives the upper limit of the CPU speed if the
|
||||
compile-time option REAL_CPU_SPEED is defined. When the CPU is reset
|
||||
it has the default value INNER_LOOP_MAX, that should be close to the
|
||||
real cpu speed (~4MHz).
|
||||
*/
|
||||
int inner_loop; /* Inner loop multiplier */
|
||||
int inner_loop_max; /* Max value of inner_loop */
|
||||
#define INNER_LOOP_MAX 26
|
||||
#define INNER_LOOP_MED 13
|
||||
#define INNER_LOOP_MIN 2
|
||||
/* 3.13: inner_loop_max gives the upper limit of the CPU speed if the
|
||||
compile-time option REAL_CPU_SPEED is defined. When the CPU is reset
|
||||
it has the default value INNER_LOOP_MAX, that should be close to the
|
||||
real cpu speed (~4MHz).
|
||||
*/
|
||||
int inner_loop; /* Inner loop multiplier */
|
||||
int inner_loop_max; /* Max value of inner_loop */
|
||||
#define INNER_LOOP_MAX 26
|
||||
#define INNER_LOOP_MED 13
|
||||
#define INNER_LOOP_MIN 2
|
||||
|
||||
#ifdef CPU_SPIN_LOOP
|
||||
int reset_req; /* Reset req. after shutdn */
|
||||
int reset_req; /* Reset req. after shutdn */
|
||||
#endif
|
||||
};
|
||||
|
||||
enum ExitOption /* 2.1: EmulatorExit() option */
|
||||
enum ExitOption /* 2.1: EmulatorExit() option */
|
||||
{
|
||||
IMMEDIATE_EXIT,
|
||||
SAVE_AND_EXIT
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Global variables
|
||||
Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
extern struct CpuStatus cpu_status;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf condition codes
|
||||
Chf condition codes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define CPU_I_CALLED 101 /* Function %s called */
|
||||
#define CPU_I_EXECUTING 102 /* Executing @PC %X */
|
||||
#define CPU_I_SHUTDN 103 /* Shutdown */
|
||||
#define CPU_I_WAKE 104 /* Wake */
|
||||
#define CPU_I_INT 105 /* %s request accepted */
|
||||
#define CPU_I_INT_PENDING 106 /* %s request pending */
|
||||
#define CPU_I_RTI_LOOP 107 /* RTI loop to service %s */
|
||||
#define CPU_I_RTI_END 108 /* RTI returning */
|
||||
#define CPU_I_INTON 109 /* INTON servicing %s */
|
||||
#define CPU_I_REVISION 110 /* CPU emulation revision: %s */
|
||||
#define CPU_I_TIMER1_EX 111 /* Timer 1 expired; ctrl=%x */
|
||||
#define CPU_I_TIMER2_EX 112 /* Timer 1 expired; ctrl=%x */
|
||||
#define CPU_I_EMULATOR_INT 113 /* Emulator interrupt req. detected */
|
||||
#define CPU_I_TIMER_ST 114 /* 3.1: Timer %s st: ctrl %x, val %x */
|
||||
#define CPU_I_TIMER_EXP 115 /* 3.1: Timer %s expiration %d ms */
|
||||
#define CPU_I_IDLE_X_LOOP 116 /* 3.1: Start idle loop, t/out %d ms */
|
||||
#define CPU_I_ELAPSED 117 /* 3.1: Spent %d us in idle loop */
|
||||
#define CPU_I_HALT 118 /* 3.13: CPU halted */
|
||||
#define CPU_I_RUN 119 /* 3.13: CPU running */
|
||||
#define CPU_W_RESETTING 201 /* Resetting CPU */
|
||||
#define CPU_W_BAD_MONITOR_CMD 202 /* Bad monitor command: %s */
|
||||
#define CPU_E_BAD_OPCODE 301 /* Bad opc. pc=%x, value=%x */
|
||||
#define CPU_E_SAVE 302 /* Can't save CPU status */
|
||||
#define CPU_E_NO_HALT 303 /* 3.13: Halt/Run not allowed */
|
||||
#define CPU_F_INTERR 401 /* Internal error %s */
|
||||
#define CPU_F_BAD_SHUTDN 402 /* Unexpected CPU shutdown */
|
||||
|
||||
#define CPU_I_CALLED 101 /* Function %s called */
|
||||
#define CPU_I_EXECUTING 102 /* Executing @PC %X */
|
||||
#define CPU_I_SHUTDN 103 /* Shutdown */
|
||||
#define CPU_I_WAKE 104 /* Wake */
|
||||
#define CPU_I_INT 105 /* %s request accepted */
|
||||
#define CPU_I_INT_PENDING 106 /* %s request pending */
|
||||
#define CPU_I_RTI_LOOP 107 /* RTI loop to service %s */
|
||||
#define CPU_I_RTI_END 108 /* RTI returning */
|
||||
#define CPU_I_INTON 109 /* INTON servicing %s */
|
||||
#define CPU_I_REVISION 110 /* CPU emulation revision: %s */
|
||||
#define CPU_I_TIMER1_EX 111 /* Timer 1 expired; ctrl=%x */
|
||||
#define CPU_I_TIMER2_EX 112 /* Timer 1 expired; ctrl=%x */
|
||||
#define CPU_I_EMULATOR_INT 113 /* Emulator interrupt req. detected */
|
||||
#define CPU_I_TIMER_ST 114 /* 3.1: Timer %s st: ctrl %x, val %x */
|
||||
#define CPU_I_TIMER_EXP 115 /* 3.1: Timer %s expiration %d ms */
|
||||
#define CPU_I_IDLE_X_LOOP 116 /* 3.1: Start idle loop, t/out %d ms */
|
||||
#define CPU_I_ELAPSED 117 /* 3.1: Spent %d us in idle loop */
|
||||
#define CPU_I_HALT 118 /* 3.13: CPU halted */
|
||||
#define CPU_I_RUN 119 /* 3.13: CPU running */
|
||||
#define CPU_W_RESETTING 201 /* Resetting CPU */
|
||||
#define CPU_W_BAD_MONITOR_CMD 202 /* Bad monitor command: %s */
|
||||
#define CPU_E_BAD_OPCODE 301 /* Bad opc. pc=%x, value=%x */
|
||||
#define CPU_E_SAVE 302 /* Can't save CPU status */
|
||||
#define CPU_E_NO_HALT 303 /* 3.13: Halt/Run not allowed */
|
||||
#define CPU_F_INTERR 401 /* Internal error %s */
|
||||
#define CPU_F_BAD_SHUTDN 402 /* Unexpected CPU shutdown */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
void CpuInit(void);
|
||||
void CpuReset(void);
|
||||
void CpuSave(void);
|
||||
void OneStep(void);
|
||||
void CpuIntRequest(enum IntRequest ireq);
|
||||
void CpuWake(void);
|
||||
void Emulator(void);
|
||||
void EmulatorIntRequest(void);
|
||||
void EmulatorInit(void); /* 2.1 */
|
||||
void EmulatorExit(enum ExitOption opt); /* 2.1 */
|
||||
int CpuHaltRequest(void); /* 3.13 */
|
||||
int CpuRunRequest(void); /* 3.13 */
|
||||
int CpuHaltAllowed(void); /* 3.13 */
|
||||
void CpuInit( void );
|
||||
void CpuReset( void );
|
||||
void CpuSave( void );
|
||||
void OneStep( void );
|
||||
void CpuIntRequest( enum IntRequest ireq );
|
||||
void CpuWake( void );
|
||||
void Emulator( void );
|
||||
void EmulatorIntRequest( void );
|
||||
void EmulatorInit( void ); /* 2.1 */
|
||||
void EmulatorExit( enum ExitOption opt ); /* 2.1 */
|
||||
int CpuHaltRequest( void ); /* 3.13 */
|
||||
int CpuRunRequest( void ); /* 3.13 */
|
||||
int CpuHaltAllowed( void ); /* 3.13 */
|
||||
|
||||
Address Disassemble(Address pc, char ob[DISASSEMBLE_OB_SIZE]);
|
||||
void DumpCpuStatus(char ob[DUMP_CPU_STATUS_OB_SIZE]);
|
||||
Address Disassemble( Address pc, char ob[ DISASSEMBLE_OB_SIZE ] );
|
||||
void DumpCpuStatus( char ob[ DUMP_CPU_STATUS_OB_SIZE ] );
|
||||
|
|
30
src/debug.c
30
src/debug.c
|
@ -73,25 +73,23 @@ static char rcs_id[] = "$Id: debug.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
#include "cpu.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID DEBUG_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID DEBUG_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Static/Global variables
|
||||
Static/Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_LEVEL
|
||||
# ifdef DEBUG_LEVEL
|
||||
int debug_level = DEBUG_LEVEL;
|
||||
#else
|
||||
# else
|
||||
int debug_level = 0;
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -105,23 +103,23 @@ int debug_level = 0;
|
|||
it signals a condition and does nothing more.
|
||||
|
||||
.call :
|
||||
SetDebugLevel(new_level)
|
||||
SetDebugLevel(new_level)
|
||||
.input :
|
||||
int new_level, new value of the debug_level flag
|
||||
int new_level, new value of the debug_level flag
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
DEBUG_W_NOT_SUPPORTED
|
||||
DEBUG_W_NOT_SUPPORTED
|
||||
.notes :
|
||||
1.1, 28-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
void SetDebugLevel(int new_level)
|
||||
void SetDebugLevel( int new_level )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
debug_level = new_level;
|
||||
debug_level = new_level;
|
||||
#else
|
||||
ChfCondition DEBUG_W_NOT_SUPPORTED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
ChfCondition DEBUG_W_NOT_SUPPORTED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
#endif
|
||||
}
|
||||
|
|
97
src/debug.h
97
src/debug.h
|
@ -44,13 +44,13 @@
|
|||
.description :
|
||||
This header defines the following macros:
|
||||
|
||||
- debug0(debug_class, condition_code)
|
||||
- debug1(debug_class, condition_code, arg_1)
|
||||
- debug2(debug_class, condition_code, arg_1, arg_2)
|
||||
- debug3(debug_class, condition_code, arg_1, arg_2, arg_3)
|
||||
- debug0(debug_class, condition_code)
|
||||
- debug1(debug_class, condition_code, arg_1)
|
||||
- debug2(debug_class, condition_code, arg_1, arg_2)
|
||||
- debug3(debug_class, condition_code, arg_1, arg_2, arg_3)
|
||||
|
||||
used throughout the source code for debugging purposes.
|
||||
|
||||
|
||||
If the DEBUG cpp symbol is defined, each invocation of these macros is
|
||||
expanded into a block of code that, at runtime, checks if the global
|
||||
variable 'debug_level' has set at least one of the bit 'debug_class' has
|
||||
|
@ -60,7 +60,7 @@
|
|||
If this condition is met, the code generates and immediately signals
|
||||
the given condition code using the Chf facility, with severity CHF_INFO,
|
||||
otherwise nothing is done.
|
||||
|
||||
|
||||
The arguments arg_1, arg_2, and arg_3 are used as additional arguments
|
||||
of the condition.
|
||||
|
||||
|
@ -101,73 +101,62 @@
|
|||
|
||||
#ifdef DEBUG
|
||||
|
||||
#define debug_preamble(debug_class, condition_code) \
|
||||
{ \
|
||||
extern int debug_level; \
|
||||
if(debug_level & (debug_class)) \
|
||||
{ \
|
||||
ChfCondition (condition_code), CHF_INFO
|
||||
# define debug_preamble( debug_class, condition_code ) \
|
||||
{ \
|
||||
extern int debug_level; \
|
||||
if ( debug_level & ( debug_class ) ) { \
|
||||
ChfCondition( condition_code ), CHF_INFO
|
||||
|
||||
#define debug_postamble \
|
||||
ChfEnd; \
|
||||
ChfSignal(); \
|
||||
} \
|
||||
}
|
||||
# define debug_postamble \
|
||||
ChfEnd; \
|
||||
ChfSignal(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define debug0(debug_class, condition_code) \
|
||||
debug_preamble(debug_class, condition_code) \
|
||||
debug_postamble
|
||||
# define debug0( debug_class, condition_code ) debug_preamble( debug_class, condition_code ) debug_postamble
|
||||
|
||||
#define debug1(debug_class, condition_code, arg_1) \
|
||||
debug_preamble(debug_class, condition_code), arg_1 \
|
||||
debug_postamble
|
||||
# define debug1( debug_class, condition_code, arg_1 ) debug_preamble( debug_class, condition_code ), arg_1 debug_postamble
|
||||
|
||||
#define debug2(debug_class, condition_code, arg_1, arg_2) \
|
||||
debug_preamble(debug_class, condition_code), arg_1, arg_2 \
|
||||
debug_postamble
|
||||
# define debug2( debug_class, condition_code, arg_1, arg_2 ) debug_preamble( debug_class, condition_code ), arg_1, arg_2 debug_postamble
|
||||
|
||||
#define debug3(debug_class, condition_code, arg_1, arg_2, arg_3) \
|
||||
debug_preamble(debug_class, condition_code), arg_1, arg_2, arg_3 \
|
||||
debug_postamble
|
||||
# define debug3( debug_class, condition_code, arg_1, arg_2, arg_3 ) \
|
||||
debug_preamble( debug_class, condition_code ), arg_1, arg_2, arg_3 debug_postamble
|
||||
|
||||
#else
|
||||
|
||||
#define debug0(debug_class, condition_code)
|
||||
#define debug1(debug_class, condition_code, arg_1)
|
||||
#define debug2(debug_class, condition_code, arg_1, arg_2)
|
||||
#define debug3(debug_class, condition_code, arg_1, arg_2, arg_3)
|
||||
# define debug0( debug_class, condition_code )
|
||||
# define debug1( debug_class, condition_code, arg_1 )
|
||||
# define debug2( debug_class, condition_code, arg_1, arg_2 )
|
||||
# define debug3( debug_class, condition_code, arg_1, arg_2, arg_3 )
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Debug classes
|
||||
Debug classes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define DEBUG_C_TRACE 0x8000 /* Function Call trace */
|
||||
#define DEBUG_C_MODULES 0x4000 /* Modules configuration */
|
||||
#define DEBUG_C_DISPLAY 0x2000 /* Display activity */
|
||||
#define DEBUG_C_INT 0x1000 /* Interrupt activity */
|
||||
#define DEBUG_C_TIMERS 0x0800 /* Timers activity */
|
||||
#define DEBUG_C_SERIAL 0x0400 /* 2.5: Serial port activity */
|
||||
#define DEBUG_C_MOD_CACHE 0x0200 /* 2.7: Module cache */
|
||||
#define DEBUG_C_IMPLEMENTATION 0x0100 /* Feature implementation */
|
||||
#define DEBUG_C_FLASH 0x0080 /* 3.3: Flash ROM */
|
||||
#define DEBUG_C_X_FUNC 0x0040 /* 3.13: Extended functions */
|
||||
#define DEBUG_C_REVISION 0x0010 /* Revision information */
|
||||
#define DEBUG_C_X11 0x0001 /* X11 Interface */
|
||||
|
||||
#define DEBUG_C_TRACE 0x8000 /* Function Call trace */
|
||||
#define DEBUG_C_MODULES 0x4000 /* Modules configuration */
|
||||
#define DEBUG_C_DISPLAY 0x2000 /* Display activity */
|
||||
#define DEBUG_C_INT 0x1000 /* Interrupt activity */
|
||||
#define DEBUG_C_TIMERS 0x0800 /* Timers activity */
|
||||
#define DEBUG_C_SERIAL 0x0400 /* 2.5: Serial port activity */
|
||||
#define DEBUG_C_MOD_CACHE 0x0200 /* 2.7: Module cache */
|
||||
#define DEBUG_C_IMPLEMENTATION 0x0100 /* Feature implementation */
|
||||
#define DEBUG_C_FLASH 0x0080 /* 3.3: Flash ROM */
|
||||
#define DEBUG_C_X_FUNC 0x0040 /* 3.13: Extended functions */
|
||||
#define DEBUG_C_REVISION 0x0010 /* Revision information */
|
||||
#define DEBUG_C_X11 0x0001 /* X11 Interface */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf condition codes
|
||||
Chf condition codes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define DEBUG_W_NOT_SUPPORTED 201 /* Debug not supported */
|
||||
#define DEBUG_W_BAD_CMD 202 /* Invalid command */
|
||||
|
||||
#define DEBUG_W_NOT_SUPPORTED 201 /* Debug not supported */
|
||||
#define DEBUG_W_BAD_CMD 202 /* Invalid command */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
void SetDebugLevel(int new_level);
|
||||
void SetDebugLevel( int new_level );
|
||||
|
|
260
src/disk_io.c
260
src/disk_io.c
|
@ -76,10 +76,9 @@ static char rcs_id[] = "$Id: disk_io.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $"
|
|||
#include "disk_io.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID DISK_IO_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID DISK_IO_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ReadNibblesFromFile
|
||||
|
@ -91,60 +90,55 @@ static char rcs_id[] = "$Id: disk_io.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $"
|
|||
caller a status code.
|
||||
|
||||
.call :
|
||||
st = ReadNibbledFromFile(name, size, dest);
|
||||
st = ReadNibbledFromFile(name, size, dest);
|
||||
.input :
|
||||
const char *name, file name
|
||||
int size, size of the file (nibbles, NOT bytes)
|
||||
const char *name, file name
|
||||
int size, size of the file (nibbles, NOT bytes)
|
||||
.output :
|
||||
Nibble *dest, pointer to the destination memory area
|
||||
int st, status code
|
||||
Nibble *dest, pointer to the destination memory area
|
||||
int st, status code
|
||||
.status_codes :
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_GETC
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_GETC
|
||||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
int ReadNibblesFromFile(const char *name, int size, Nibble *dest)
|
||||
int ReadNibblesFromFile( const char* name, int size, Nibble* dest )
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
int by;
|
||||
int st = DISK_IO_S_OK;
|
||||
FILE* f;
|
||||
int i;
|
||||
int by;
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1(DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadNibblesFromFile");
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadNibblesFromFile" );
|
||||
|
||||
if((f = fopen(name, "rb")) == (FILE *)NULL)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
for(i=0; i<size;)
|
||||
{
|
||||
by = getc(f);
|
||||
|
||||
if(by == -1)
|
||||
{
|
||||
if ( ( f = fopen( name, "rb" ) ) == ( FILE* )NULL ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
dest[i++] = (Nibble)(by & 0x0F);
|
||||
dest[i++] = (Nibble)((by & 0xF0) >> 4);
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
(void)fclose(f);
|
||||
}
|
||||
else {
|
||||
for ( i = 0; i < size; ) {
|
||||
by = getc( f );
|
||||
|
||||
return st;
|
||||
if ( by == -1 ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
dest[ i++ ] = ( Nibble )( by & 0x0F );
|
||||
dest[ i++ ] = ( Nibble )( ( by & 0xF0 ) >> 4 );
|
||||
}
|
||||
|
||||
( void )fclose( f );
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : WriteNibblesToFile
|
||||
|
@ -155,63 +149,57 @@ int ReadNibblesFromFile(const char *name, int size, Nibble *dest)
|
|||
It returns to the caller a status code
|
||||
|
||||
.call :
|
||||
st = WriteNibblesToFile(src, size, name);
|
||||
st = WriteNibblesToFile(src, size, name);
|
||||
.input :
|
||||
const Nibble *src, pointer to data to be written
|
||||
int size, # of nibble to write
|
||||
const char *name, file name
|
||||
const Nibble *src, pointer to data to be written
|
||||
int size, # of nibble to write
|
||||
const char *name, file name
|
||||
.output :
|
||||
int st, status code
|
||||
int st, status code
|
||||
.status_codes :
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_PUTC
|
||||
DISK_IO_E_CLOSE
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_PUTC
|
||||
DISK_IO_E_CLOSE
|
||||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
int WriteNibblesToFile(const Nibble *src, int size, const char *name)
|
||||
int WriteNibblesToFile( const Nibble* src, int size, const char* name )
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
int by;
|
||||
int st = DISK_IO_S_OK;
|
||||
FILE* f;
|
||||
int i;
|
||||
int by;
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1(DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteNibblesToFile");
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteNibblesToFile" );
|
||||
|
||||
if((f = fopen(name, "wb")) == (FILE *)NULL)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
for(i=0; i<size;)
|
||||
{
|
||||
by = (int)src[i++];
|
||||
by |= (int)src[i++] << 4;
|
||||
|
||||
if(putc(by, f) == EOF)
|
||||
{
|
||||
if ( ( f = fopen( name, "wb" ) ) == ( FILE* )NULL ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
if(fclose(f) == EOF)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( i = 0; i < size; ) {
|
||||
by = ( int )src[ i++ ];
|
||||
by |= ( int )src[ i++ ] << 4;
|
||||
|
||||
return st;
|
||||
if ( putc( by, f ) == EOF ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fclose( f ) == EOF ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ReadStructFromFile
|
||||
|
@ -222,48 +210,44 @@ int WriteNibblesToFile(const Nibble *src, int size, const char *name)
|
|||
from the disk file 'name' and returns a status code to the caller.
|
||||
|
||||
.call :
|
||||
st = ReadStructFromFile(name, s_size, s);
|
||||
st = ReadStructFromFile(name, s_size, s);
|
||||
.input :
|
||||
const char *name, file name
|
||||
size_t s_size, structure size
|
||||
const char *name, file name
|
||||
size_t s_size, structure size
|
||||
.output :
|
||||
void *s, pointer to the structure
|
||||
void *s, pointer to the structure
|
||||
.status_codes :
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_READ
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_READ
|
||||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
int ReadStructFromFile(const char *name, size_t s_size, void *s)
|
||||
int ReadStructFromFile( const char* name, size_t s_size, void* s )
|
||||
{
|
||||
FILE *f;
|
||||
int st = DISK_IO_S_OK;
|
||||
FILE* f;
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1(DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadStructFromFile");
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadStructFromFile" );
|
||||
|
||||
if((f = fopen(name, "rb")) == (FILE *)NULL)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if(fread(s, s_size, (size_t)1, f) != 1)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_READ, CHF_ERROR, name ChfEnd;
|
||||
if ( ( f = fopen( name, "rb" ) ) == ( FILE* )NULL ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
(void)fclose(f);
|
||||
}
|
||||
else {
|
||||
if ( fread( s, s_size, ( size_t )1, f ) != 1 ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_READ, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
return st;
|
||||
( void )fclose( f );
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : WriteStructToFile
|
||||
|
@ -274,49 +258,45 @@ int ReadStructFromFile(const char *name, size_t s_size, void *s)
|
|||
'name' and returns to the caller a status code.
|
||||
|
||||
.call :
|
||||
st =WriteStructToFile(s, s_size, name);
|
||||
st =WriteStructToFile(s, s_size, name);
|
||||
.input :
|
||||
const void *s, pointer to the structure to be written
|
||||
size_t s_size, structure size
|
||||
const char *name, output file name
|
||||
const void *s, pointer to the structure to be written
|
||||
size_t s_size, structure size
|
||||
const char *name, output file name
|
||||
.output :
|
||||
int st, status code
|
||||
int st, status code
|
||||
.status_codes :
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_WRITE
|
||||
DISK_IO_E_CLOSE
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_WRITE
|
||||
DISK_IO_E_CLOSE
|
||||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
int WriteStructToFile(const void *s, size_t s_size, const char *name)
|
||||
int WriteStructToFile( const void* s, size_t s_size, const char* name )
|
||||
{
|
||||
FILE *f;
|
||||
int st = DISK_IO_S_OK;
|
||||
FILE* f;
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1(DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteStructToFile");
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteStructToFile" );
|
||||
|
||||
if((f = fopen(name, "wb")) == (FILE *)NULL)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if(fwrite(s, s_size, (size_t)1, f) != 1)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_WRITE, CHF_ERROR, name ChfEnd;
|
||||
if ( ( f = fopen( name, "wb" ) ) == ( FILE* )NULL ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
if(fclose(f) == EOF)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( fwrite( s, s_size, ( size_t )1, f ) != 1 ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_WRITE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
return st;
|
||||
if ( fclose( f ) == EOF ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
|
|
@ -68,33 +68,29 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf condition codes
|
||||
Chf condition codes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define DISK_IO_S_OK 0 /* Function completed succesfully */
|
||||
#define DISK_IO_I_CALLED 101 /* Function %s called */
|
||||
#define DISK_IO_E_OPEN 401 /* Open file %s failed */
|
||||
#define DISK_IO_E_GETC 402 /* getc() from file %s failed */
|
||||
#define DISK_IO_E_PUTC 403 /* putc() to file %s failed */
|
||||
#define DISK_IO_E_READ 404 /* fread() from file %s failed */
|
||||
#define DISK_IO_E_WRITE 405 /* fwrite() to file %s failed */
|
||||
#define DISK_IO_E_CLOSE 406 /* Close file %s failed */
|
||||
#define DISK_IO_E_BAD_HDR 407 /* File %s has a bad header */
|
||||
#define DISK_IO_E_SIZE 408 /* File %s too large */
|
||||
|
||||
#define DISK_IO_S_OK 0 /* Function completed succesfully */
|
||||
#define DISK_IO_I_CALLED 101 /* Function %s called */
|
||||
#define DISK_IO_E_OPEN 401 /* Open file %s failed */
|
||||
#define DISK_IO_E_GETC 402 /* getc() from file %s failed */
|
||||
#define DISK_IO_E_PUTC 403 /* putc() to file %s failed */
|
||||
#define DISK_IO_E_READ 404 /* fread() from file %s failed */
|
||||
#define DISK_IO_E_WRITE 405 /* fwrite() to file %s failed */
|
||||
#define DISK_IO_E_CLOSE 406 /* Close file %s failed */
|
||||
#define DISK_IO_E_BAD_HDR 407 /* File %s has a bad header */
|
||||
#define DISK_IO_E_SIZE 408 /* File %s too large */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
int ReadNibblesFromFile(const char *name, int size, Nibble *dest);
|
||||
int WriteNibblesToFile(const Nibble *src, int size, const char *name);
|
||||
int ReadStructFromFile(const char *name, size_t s_size, void *s);
|
||||
int WriteStructToFile(const void *s, size_t s_size, const char *name);
|
||||
int ReadNibblesFromFile( const char* name, int size, Nibble* dest );
|
||||
int WriteNibblesToFile( const Nibble* src, int size, const char* name );
|
||||
int ReadStructFromFile( const char* name, size_t s_size, void* s );
|
||||
int WriteStructToFile( const void* s, size_t s_size, const char* name );
|
||||
|
||||
int ReadObjectFromFile(
|
||||
const char *name, const char *hdr, Address start, Address end);
|
||||
int WriteObjectToFile(
|
||||
Address start, Address end, const char *hdr, const char *name);
|
||||
int ReadObjectFromFile( const char* name, const char* hdr, Address start, Address end );
|
||||
int WriteObjectToFile( Address start, Address end, const char* hdr, const char* name );
|
||||
|
|
|
@ -75,10 +75,9 @@ static char rcs_id[] = "$Id: disk_io_obj.c,v 4.1 2000/12/11 09:54:19 cibrario Re
|
|||
#include "disk_io.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID DISK_IO_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID DISK_IO_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ReadObjectFromFile
|
||||
|
@ -104,111 +103,100 @@ static char rcs_id[] = "$Id: disk_io_obj.c,v 4.1 2000/12/11 09:54:19 cibrario Re
|
|||
This function returns to the caller a status code.
|
||||
|
||||
.call :
|
||||
st = ReadObjectFromFile(name, hdr, start, end);
|
||||
st = ReadObjectFromFile(name, hdr, start, end);
|
||||
|
||||
.input :
|
||||
const char *name, input file name
|
||||
const char *hdr, file header
|
||||
Address start, start address (inclusive)
|
||||
Address end, end address (exclusive)
|
||||
const char *name, input file name
|
||||
const char *hdr, file header
|
||||
Address start, start address (inclusive)
|
||||
Address end, end address (exclusive)
|
||||
.output :
|
||||
int st, status code
|
||||
int st, status code
|
||||
.status_codes :
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_GETC
|
||||
DISK_IO_E_BAD_HDR
|
||||
DISK_IO_E_SIZE
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_GETC
|
||||
DISK_IO_E_BAD_HDR
|
||||
DISK_IO_E_SIZE
|
||||
.notes :
|
||||
3.14, 10-Nov-2000, creation
|
||||
|
||||
.- */
|
||||
int ReadObjectFromFile(
|
||||
const char *name, const char *hdr, Address start, Address end)
|
||||
int ReadObjectFromFile( const char* name, const char* hdr, Address start, Address end )
|
||||
{
|
||||
size_t hdr_len = strlen(hdr);
|
||||
FILE *f;
|
||||
size_t hdr_len = strlen( hdr );
|
||||
FILE* f;
|
||||
int i;
|
||||
int by;
|
||||
Address cur;
|
||||
|
||||
#define N_SAVE_AREA 10
|
||||
Nibble save_area[N_SAVE_AREA];
|
||||
#define N_SAVE_AREA 10
|
||||
Nibble save_area[ N_SAVE_AREA ];
|
||||
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1(DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadObjectFromFile");
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadObjectFromFile" );
|
||||
|
||||
/* Save first nibbles of target space into save_area */
|
||||
for(cur=start, i=0; cur < end && i<N_SAVE_AREA; cur++, i++)
|
||||
save_area[i] = ReadNibble(cur);
|
||||
for ( cur = start, i = 0; cur < end && i < N_SAVE_AREA; cur++, i++ )
|
||||
save_area[ i ] = ReadNibble( cur );
|
||||
|
||||
if((f = fopen(name, "rb")) == (FILE *)NULL)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
if ( ( f = fopen( name, "rb" ) ) == ( FILE* )NULL ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Check and skip header */
|
||||
for(i=0; i<hdr_len; i++)
|
||||
{
|
||||
by = getc(f);
|
||||
else {
|
||||
/* Check and skip header */
|
||||
for ( i = 0; i < hdr_len; i++ ) {
|
||||
by = getc( f );
|
||||
|
||||
if(by == EOF)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
if ( by == EOF ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
else if(hdr[i] != '?' && by != hdr[i])
|
||||
{
|
||||
ChfCondition st=DISK_IO_E_BAD_HDR, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( hdr[ i ] != '?' && by != hdr[ i ] ) {
|
||||
ChfCondition st = DISK_IO_E_BAD_HDR, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(st == DISK_IO_S_OK)
|
||||
{
|
||||
cur = start;
|
||||
if ( st == DISK_IO_S_OK ) {
|
||||
cur = start;
|
||||
|
||||
/* Header check/skip OK; transfer */
|
||||
while((by = getc(f)) != EOF)
|
||||
{
|
||||
/* Next byte available in by; check available space */
|
||||
if(cur >= end-1)
|
||||
{
|
||||
ChfCondition st=DISK_IO_E_SIZE, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
/* Header check/skip OK; transfer */
|
||||
while ( ( by = getc( f ) ) != EOF ) {
|
||||
/* Next byte available in by; check available space */
|
||||
if ( cur >= end - 1 ) {
|
||||
ChfCondition st = DISK_IO_E_SIZE, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Store it */
|
||||
WriteNibble(cur++, (Nibble)(by & 0x0F));
|
||||
WriteNibble(cur++, (Nibble)((by & 0xF0) >> 4));
|
||||
}
|
||||
/* Store it */
|
||||
WriteNibble( cur++, ( Nibble )( by & 0x0F ) );
|
||||
WriteNibble( cur++, ( Nibble )( ( by & 0xF0 ) >> 4 ) );
|
||||
}
|
||||
|
||||
/* Check why getc() failed */
|
||||
if(ferror(f) && !feof(f))
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
/* Check why getc() failed */
|
||||
if ( ferror( f ) && !feof( f ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
/* Recover from save_area if transfer failed */
|
||||
if(st)
|
||||
for(cur=start, i=0; cur < end && i<N_SAVE_AREA; cur++, i++)
|
||||
WriteNibble(cur, save_area[i]);
|
||||
}
|
||||
/* Recover from save_area if transfer failed */
|
||||
if ( st )
|
||||
for ( cur = start, i = 0; cur < end && i < N_SAVE_AREA; cur++, i++ )
|
||||
WriteNibble( cur, save_area[ i ] );
|
||||
}
|
||||
|
||||
(void)fclose(f);
|
||||
( void )fclose( f );
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : WriteObjectToFile
|
||||
|
@ -225,92 +213,81 @@ int ReadObjectFromFile(
|
|||
This function returns to the caller a status code.
|
||||
|
||||
.call :
|
||||
st = WriteObjectToFile(start, end, hdr, name);
|
||||
st = WriteObjectToFile(start, end, hdr, name);
|
||||
.input :
|
||||
Address start, start address (inclusive)
|
||||
Address end, end address (exclusive)
|
||||
const char *hdr, file header
|
||||
const char *name, output file name
|
||||
Address start, start address (inclusive)
|
||||
Address end, end address (exclusive)
|
||||
const char *hdr, file header
|
||||
const char *name, output file name
|
||||
.output :
|
||||
int st, status code
|
||||
int st, status code
|
||||
.status_codes :
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_PUTC
|
||||
DISK_IO_E_CLOSE
|
||||
DISK_IO_I_CALLED (signalled)
|
||||
DISK_IO_E_OPEN
|
||||
DISK_IO_E_PUTC
|
||||
DISK_IO_E_CLOSE
|
||||
.notes :
|
||||
3.14, 10-Nov-2000, creation
|
||||
|
||||
.- */
|
||||
int WriteObjectToFile(
|
||||
Address start, Address end, const char *hdr, const char *name)
|
||||
int WriteObjectToFile( Address start, Address end, const char* hdr, const char* name )
|
||||
{
|
||||
size_t hdr_len = strlen(hdr);
|
||||
FILE *f;
|
||||
size_t hdr_len = strlen( hdr );
|
||||
FILE* f;
|
||||
int i;
|
||||
int by;
|
||||
Address cur;
|
||||
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1(DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteObjectFromFile");
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteObjectFromFile" );
|
||||
|
||||
if((f = fopen(name, "wb")) == (FILE *)NULL)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
if ( ( f = fopen( name, "wb" ) ) == ( FILE* )NULL ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Write header; replace wildcard character '?' with 'S' */
|
||||
for(i=0; i<hdr_len; i++)
|
||||
{
|
||||
if(putc(hdr[i] == '?' ? 'S' : hdr[i], f) == EOF)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Write header; replace wildcard character '?' with 'S' */
|
||||
for ( i = 0; i < hdr_len; i++ ) {
|
||||
if ( putc( hdr[ i ] == '?' ? 'S' : hdr[ i ], f ) == EOF ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(st == DISK_IO_S_OK)
|
||||
{
|
||||
cur = start;
|
||||
if ( st == DISK_IO_S_OK ) {
|
||||
cur = start;
|
||||
|
||||
while(cur < end-1)
|
||||
{
|
||||
/* Make a byte with two nibbles */
|
||||
by = (int)ReadNibble(cur++);
|
||||
by |= (int)ReadNibble(cur++) << 4;
|
||||
while ( cur < end - 1 ) {
|
||||
/* Make a byte with two nibbles */
|
||||
by = ( int )ReadNibble( cur++ );
|
||||
by |= ( int )ReadNibble( cur++ ) << 4;
|
||||
|
||||
if(putc(by, f) == EOF)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( putc( by, f ) == EOF ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the last odd nibble, if necessary */
|
||||
if(st == DISK_IO_S_OK && cur == end-1)
|
||||
{
|
||||
by = (int)ReadNibble(cur++);
|
||||
/* Write the last odd nibble, if necessary */
|
||||
if ( st == DISK_IO_S_OK && cur == end - 1 ) {
|
||||
by = ( int )ReadNibble( cur++ );
|
||||
|
||||
if(putc(by, f) == EOF)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( putc( by, f ) == EOF ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the output file anyway */
|
||||
if(fclose(f) == EOF)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st=DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
/* Close the output file anyway */
|
||||
if ( fclose( f ) == EOF ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
|
||||
return st;
|
||||
|
|
596
src/display.c
596
src/display.c
|
@ -43,7 +43,7 @@
|
|||
.keywords : *
|
||||
.description :
|
||||
This source module emulates the Lcd driver of the Yorke chip.
|
||||
|
||||
|
||||
References:
|
||||
|
||||
SASM.DOC by HP (HORN disk 4)
|
||||
|
@ -52,10 +52,10 @@
|
|||
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.
|
||||
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
|
||||
|
||||
|
@ -97,7 +97,7 @@ static char rcs_id[] = "$Id: display.c,v 4.1.1.1 2002/11/11 16:12:46 cibrario Ex
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h> /* 3.1: memset() */
|
||||
#include <string.h> /* 3.1: memset() */
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
|
@ -109,157 +109,121 @@ static char rcs_id[] = "$Id: display.c,v 4.1.1.1 2002/11/11 16:12:46 cibrario Ex
|
|||
#include "x11.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID X11_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID X11_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
#ifndef LCD_MAG
|
||||
# define LCD_MAG 2 /* 4.1.1.1: Compat. default */
|
||||
# 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 */
|
||||
#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 */
|
||||
#if LCD_MAG == 1
|
||||
# define LCD_Y_ORIGIN 14 /* y origin */
|
||||
#else
|
||||
# define LCD_Y_ORIGIN 20 /* y origin */
|
||||
# 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
|
||||
#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/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 } /* **** */
|
||||
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 */
|
||||
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
|
||||
}
|
||||
}
|
||||
#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 Nibble lcd_buffer[ MAX_ROWS ][ NIBBLES_PER_ROW ];
|
||||
static int ann_buffer;
|
||||
static int clean;
|
||||
|
||||
static Display *display;
|
||||
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];
|
||||
|
||||
static Pixmap nibble_pixmap[ NIBBLE_VALUES ];
|
||||
static Pixmap ann_pixmap[ N_ANN ];
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private functions
|
||||
Private functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -272,56 +236,43 @@ static Pixmap ann_pixmap[N_ANN];
|
|||
stores them into the appropriate global variables.
|
||||
|
||||
.call :
|
||||
InitPixmaps();
|
||||
InitPixmaps();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
X11_F_X_ERROR
|
||||
X11_I_CALLED
|
||||
X11_F_X_ERROR
|
||||
.notes :
|
||||
1.1, 29-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
static void InitPixmaps(void)
|
||||
static void InitPixmaps( void )
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
debug1(DEBUG_C_TRACE, X11_I_CALLED, "InitPixmaps");
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "InitPixmaps" );
|
||||
|
||||
/* Initialize nibble_pixmap */
|
||||
for(i=0; i<NIBBLE_VALUES; i++)
|
||||
{
|
||||
if((nibble_pixmap[i] =
|
||||
XCreatePixmapFromBitmapData(
|
||||
display, window, nibble_bitmap_data[i], 4*LCD_MAG, LCD_MAG,
|
||||
fg_pixel, bg_pixel, depth
|
||||
)) ==
|
||||
None)
|
||||
{
|
||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
/* Initialize nibble_pixmap */
|
||||
for ( i = 0; i < NIBBLE_VALUES; i++ ) {
|
||||
if ( ( nibble_pixmap[ i ] = XCreatePixmapFromBitmapData( display, window, nibble_bitmap_data[ i ], 4 * LCD_MAG, LCD_MAG, fg_pixel,
|
||||
bg_pixel, depth ) ) == None ) {
|
||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize ann_pixmap */
|
||||
for (i=0; i<N_ANN; i++)
|
||||
{
|
||||
if((ann_pixmap[i] =
|
||||
XCreatePixmapFromBitmapData(display, window,
|
||||
ann_data[i].bitmap_data, ann_data[i].w, ann_data[i].h,
|
||||
fg_pixel, bg_pixel, depth
|
||||
)) ==
|
||||
None)
|
||||
{
|
||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
/* Initialize ann_pixmap */
|
||||
for ( i = 0; i < N_ANN; i++ ) {
|
||||
if ( ( ann_pixmap[ i ] = XCreatePixmapFromBitmapData( display, window, ann_data[ i ].bitmap_data, ann_data[ i ].w, ann_data[ i ].h,
|
||||
fg_pixel, bg_pixel, depth ) ) == None ) {
|
||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ClearLcd
|
||||
|
@ -331,32 +282,31 @@ static void InitPixmaps(void)
|
|||
This function clears the Lcd screen
|
||||
|
||||
.call :
|
||||
ClearLcd();
|
||||
ClearLcd();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
X11_I_CALLED
|
||||
.notes :
|
||||
1.1, 29-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
static void ClearLcd(void)
|
||||
static void ClearLcd( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, X11_I_CALLED, "ClearLcd");
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "ClearLcd" );
|
||||
|
||||
/* Clear Lcd display */
|
||||
(void)memset((void *)lcd_buffer, 0, sizeof(lcd_buffer));
|
||||
ann_buffer = 0;
|
||||
/* Clear Lcd display */
|
||||
( void )memset( ( void* )lcd_buffer, 0, sizeof( lcd_buffer ) );
|
||||
ann_buffer = 0;
|
||||
|
||||
XClearWindow(display, window);
|
||||
XFlush(display);
|
||||
XClearWindow( display, window );
|
||||
XFlush( display );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public funcitons
|
||||
Public funcitons
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -369,86 +319,79 @@ static void ClearLcd(void)
|
|||
The LCD screen is initially cleared.
|
||||
|
||||
.call :
|
||||
InitLcd(lcd_display, lcd_window, lcd_fg_pixel, lcd_bg_pixel);
|
||||
InitLcd(lcd_display, lcd_window, lcd_fg_pixel, lcd_bg_pixel);
|
||||
.input :
|
||||
Display *lcd_display, X display
|
||||
Window lcd_window, X window to be used for display
|
||||
unsigned long lcd_fg_pixel, foreground color to be used
|
||||
unsigned long lcd_bg_pixel, background color to be used
|
||||
Display *lcd_display, X display
|
||||
Window lcd_window, X window to be used for display
|
||||
unsigned long lcd_fg_pixel, foreground color to be used
|
||||
unsigned long lcd_bg_pixel, background color to be used
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
X11_F_X_ERROR
|
||||
X11_I_CALLED
|
||||
X11_F_X_ERROR
|
||||
.notes :
|
||||
1.1, 29-Jan-1998, creation
|
||||
3.8, 23-Oct-2000, bug fix:
|
||||
- added clip rectangle to GC, to avoid drawing non-existent pixels.
|
||||
|
||||
.- */
|
||||
void InitLcd(Display *lcd_display, Window lcd_window,
|
||||
unsigned long lcd_fg_pixel, unsigned long lcd_bg_pixel)
|
||||
void InitLcd( Display* lcd_display, Window lcd_window, unsigned long lcd_fg_pixel, unsigned long lcd_bg_pixel )
|
||||
{
|
||||
XWindowAttributes xwa;
|
||||
XGCValues gc_values;
|
||||
|
||||
debug1(DEBUG_C_TRACE, X11_I_CALLED, "InitLcdWindow");
|
||||
XWindowAttributes xwa;
|
||||
XGCValues gc_values;
|
||||
|
||||
display = lcd_display;
|
||||
window = lcd_window;
|
||||
fg_pixel = lcd_fg_pixel;
|
||||
bg_pixel = lcd_bg_pixel;
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "InitLcdWindow" );
|
||||
|
||||
/* Get window attributes and initialize window depth */
|
||||
if(XGetWindowAttributes(display, window, &xwa) == 0)
|
||||
{
|
||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
display = lcd_display;
|
||||
window = lcd_window;
|
||||
fg_pixel = lcd_fg_pixel;
|
||||
bg_pixel = lcd_bg_pixel;
|
||||
|
||||
depth = xwa.depth;
|
||||
/* Get window attributes and initialize window depth */
|
||||
if ( XGetWindowAttributes( display, window, &xwa ) == 0 ) {
|
||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Create GC */
|
||||
gc_values.function = GXcopy;
|
||||
gc_values.plane_mask = AllPlanes;
|
||||
gc_values.subwindow_mode = IncludeInferiors;
|
||||
gc_values.foreground = lcd_fg_pixel;
|
||||
gc_values.background = lcd_bg_pixel;
|
||||
gc_values.graphics_exposures = False;
|
||||
depth = xwa.depth;
|
||||
|
||||
gc = XCreateGC(display, window,
|
||||
GCFunction|GCPlaneMask|GCForeground|GCBackground|GCSubwindowMode|
|
||||
GCGraphicsExposures,
|
||||
&gc_values);
|
||||
/* Create GC */
|
||||
gc_values.function = GXcopy;
|
||||
gc_values.plane_mask = AllPlanes;
|
||||
gc_values.subwindow_mode = IncludeInferiors;
|
||||
gc_values.foreground = lcd_fg_pixel;
|
||||
gc_values.background = lcd_bg_pixel;
|
||||
gc_values.graphics_exposures = False;
|
||||
|
||||
{
|
||||
/* 3.8: This clip rectangle prevents XCopyArea() (in DrawLcd()) from
|
||||
drawing non-visible pixels
|
||||
*/
|
||||
XRectangle rect[1];
|
||||
gc = XCreateGC( display, window, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCSubwindowMode | GCGraphicsExposures,
|
||||
&gc_values );
|
||||
|
||||
rect[0].x = LCD_CLIP_X_ORIGIN; /* This is the clip rectangle */
|
||||
rect[0].y = LCD_CLIP_Y_ORIGIN;
|
||||
rect[0].width = LCD_CLIP_WIDTH;
|
||||
rect[0].height = LCD_CLIP_HEIGHT;
|
||||
{
|
||||
/* 3.8: This clip rectangle prevents XCopyArea() (in DrawLcd()) from
|
||||
drawing non-visible pixels
|
||||
*/
|
||||
XRectangle rect[ 1 ];
|
||||
|
||||
XSetClipRectangles(
|
||||
display, gc,
|
||||
0, 0, /* Alsolute clip X,Y origin */
|
||||
rect, 1, YXBanded);
|
||||
}
|
||||
rect[ 0 ].x = LCD_CLIP_X_ORIGIN; /* This is the clip rectangle */
|
||||
rect[ 0 ].y = LCD_CLIP_Y_ORIGIN;
|
||||
rect[ 0 ].width = LCD_CLIP_WIDTH;
|
||||
rect[ 0 ].height = LCD_CLIP_HEIGHT;
|
||||
|
||||
/* Initialize Pixmaps */
|
||||
InitPixmaps();
|
||||
XSetClipRectangles( display, gc, 0, 0, /* Alsolute clip X,Y origin */
|
||||
rect, 1, YXBanded );
|
||||
}
|
||||
|
||||
/* Clear screen and initialize the static memory areas */
|
||||
ClearLcd();
|
||||
/* Initialize Pixmaps */
|
||||
InitPixmaps();
|
||||
|
||||
/* Set the 'display is clean' flag */
|
||||
clean = 1;
|
||||
/* Clear screen and initialize the static memory areas */
|
||||
ClearLcd();
|
||||
|
||||
/* Set the 'display is clean' flag */
|
||||
clean = 1;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : DrawLcd
|
||||
|
@ -459,146 +402,113 @@ void InitLcd(Display *lcd_display, Window lcd_window,
|
|||
the mod_status.hdw structure.
|
||||
|
||||
.call :
|
||||
DrawLcd();
|
||||
DrawLcd();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
X11_I_LCD_PAR
|
||||
X11_I_CALLED
|
||||
X11_I_LCD_PAR
|
||||
.notes :
|
||||
1.1, 29-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
void DrawLcd(void)
|
||||
void DrawLcd( void )
|
||||
{
|
||||
Address addr = mod_status.hdw.lcd_base_addr;
|
||||
int y, x;
|
||||
Nibble v;
|
||||
Address addr = mod_status.hdw.lcd_base_addr;
|
||||
int y, x;
|
||||
Nibble v;
|
||||
|
||||
debug1(DEBUG_C_TRACE, X11_I_CALLED, "DrawLcd");
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "DrawLcd" );
|
||||
|
||||
/* If the debug class DEBUG_C_DISPLAY is enabled, print the display
|
||||
parameters
|
||||
*/
|
||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_base_addr",
|
||||
(int)mod_status.hdw.lcd_base_addr);
|
||||
/* If the debug class DEBUG_C_DISPLAY is enabled, print the display
|
||||
parameters
|
||||
*/
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_base_addr", ( int )mod_status.hdw.lcd_base_addr );
|
||||
|
||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_on",
|
||||
(int)mod_status.hdw.lcd_on);
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_on", ( int )mod_status.hdw.lcd_on );
|
||||
|
||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_contrast",
|
||||
(int)mod_status.hdw.lcd_contrast);
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_contrast", ( int )mod_status.hdw.lcd_contrast );
|
||||
|
||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_vlc",
|
||||
(int)mod_status.hdw.lcd_vlc);
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_vlc", ( int )mod_status.hdw.lcd_vlc );
|
||||
|
||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_offset",
|
||||
(int)mod_status.hdw.lcd_offset);
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_offset", ( int )mod_status.hdw.lcd_offset );
|
||||
|
||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_line_offset",
|
||||
(int)mod_status.hdw.lcd_line_offset);
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_line_offset", ( int )mod_status.hdw.lcd_line_offset );
|
||||
|
||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_menu_addr",
|
||||
(int)mod_status.hdw.lcd_menu_addr);
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_menu_addr", ( int )mod_status.hdw.lcd_menu_addr );
|
||||
|
||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_ann",
|
||||
(int)mod_status.hdw.lcd_ann);
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_ann", ( int )mod_status.hdw.lcd_ann );
|
||||
|
||||
/* Check if display is on */
|
||||
if(!mod_status.hdw.lcd_on)
|
||||
{
|
||||
/* Display is off; clear lcd if necessary */
|
||||
if(!clean)
|
||||
{
|
||||
/* Set the 'display is clean' flag and clear the screen */
|
||||
clean = 1;
|
||||
ClearLcd();
|
||||
/* Check if display is on */
|
||||
if ( !mod_status.hdw.lcd_on ) {
|
||||
/* Display is off; clear lcd if necessary */
|
||||
if ( !clean ) {
|
||||
/* Set the 'display is clean' flag and clear the screen */
|
||||
clean = 1;
|
||||
ClearLcd();
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* The display is on and will be no longer clean */
|
||||
clean = 0;
|
||||
/* The display is on and will be no longer clean */
|
||||
clean = 0;
|
||||
|
||||
/* Scan active display rows */
|
||||
for(y=0; y<=mod_status.hdw.lcd_vlc; y++)
|
||||
{
|
||||
/* Scan columns */
|
||||
for(x=0; x<NIBBLES_PER_ROW; x++)
|
||||
{
|
||||
v = FetchNibble(addr++);
|
||||
if( v != lcd_buffer[y][x] )
|
||||
{
|
||||
lcd_buffer[y][x] = v;
|
||||
/* Scan active display rows */
|
||||
for ( y = 0; y <= mod_status.hdw.lcd_vlc; y++ ) {
|
||||
/* Scan columns */
|
||||
for ( x = 0; x < NIBBLES_PER_ROW; x++ ) {
|
||||
v = FetchNibble( addr++ );
|
||||
if ( v != lcd_buffer[ y ][ x ] ) {
|
||||
lcd_buffer[ y ][ x ] = v;
|
||||
|
||||
XCopyArea(display, nibble_pixmap[(int)v], window, gc,
|
||||
0, 0, /* src_x, src_y */
|
||||
4*LCD_MAG, LCD_MAG, /* width, height */
|
||||
x*4*LCD_MAG + LCD_X_ORIGIN,
|
||||
y*LCD_MAG + LCD_Y_ORIGIN
|
||||
);
|
||||
}
|
||||
XCopyArea( display, nibble_pixmap[ ( int )v ], window, gc, 0, 0, /* src_x, src_y */
|
||||
4 * LCD_MAG, LCD_MAG, /* width, height */
|
||||
x * 4 * LCD_MAG + LCD_X_ORIGIN, y * LCD_MAG + LCD_Y_ORIGIN );
|
||||
}
|
||||
}
|
||||
|
||||
addr += mod_status.hdw.lcd_line_offset;
|
||||
}
|
||||
|
||||
addr += mod_status.hdw.lcd_line_offset;
|
||||
}
|
||||
|
||||
/* Scan menu display rows */
|
||||
addr = mod_status.hdw.lcd_menu_addr;
|
||||
for(; y<MAX_ROWS; y++)
|
||||
{
|
||||
/* Scan columns */
|
||||
for(x=0; x<NIBBLES_PER_ROW; x++)
|
||||
{
|
||||
v = FetchNibble(addr++);
|
||||
if( v != lcd_buffer[y][x] )
|
||||
{
|
||||
lcd_buffer[y][x] = v;
|
||||
XCopyArea(display, nibble_pixmap[(int)v], window, gc,
|
||||
0, 0, /* src_x, src_y */
|
||||
4*LCD_MAG, LCD_MAG, /* width, height */
|
||||
x*4*LCD_MAG + LCD_X_ORIGIN,
|
||||
y*LCD_MAG + LCD_Y_ORIGIN
|
||||
);
|
||||
}
|
||||
/* Scan menu display rows */
|
||||
addr = mod_status.hdw.lcd_menu_addr;
|
||||
for ( ; y < MAX_ROWS; y++ ) {
|
||||
/* Scan columns */
|
||||
for ( x = 0; x < NIBBLES_PER_ROW; x++ ) {
|
||||
v = FetchNibble( addr++ );
|
||||
if ( v != lcd_buffer[ y ][ x ] ) {
|
||||
lcd_buffer[ y ][ x ] = v;
|
||||
XCopyArea( display, nibble_pixmap[ ( int )v ], window, gc, 0, 0, /* src_x, src_y */
|
||||
4 * LCD_MAG, LCD_MAG, /* width, height */
|
||||
x * 4 * LCD_MAG + LCD_X_ORIGIN, y * LCD_MAG + LCD_Y_ORIGIN );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan annunciators */
|
||||
if(mod_status.hdw.lcd_ann != ann_buffer)
|
||||
{
|
||||
ann_buffer = mod_status.hdw.lcd_ann;
|
||||
/* Scan annunciators */
|
||||
if ( mod_status.hdw.lcd_ann != ann_buffer ) {
|
||||
ann_buffer = mod_status.hdw.lcd_ann;
|
||||
|
||||
for(y=0; y<N_ANN; y++)
|
||||
{
|
||||
if((ann_buffer & ann_data[y].mask) == ann_data[y].mask)
|
||||
{
|
||||
XCopyArea(display, ann_pixmap[y], window, gc,
|
||||
0, 0, /* src_x, src_y */
|
||||
ann_data[y].w, ann_data[y].h, /* width, height */
|
||||
ann_data[y].x,
|
||||
ann_data[y].y
|
||||
);
|
||||
}
|
||||
for ( y = 0; y < N_ANN; y++ ) {
|
||||
if ( ( ann_buffer & ann_data[ y ].mask ) == ann_data[ y ].mask ) {
|
||||
XCopyArea( display, ann_pixmap[ y ], window, gc, 0, 0, /* src_x, src_y */
|
||||
ann_data[ y ].w, ann_data[ y ].h, /* width, height */
|
||||
ann_data[ y ].x, ann_data[ y ].y );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
XClearArea(display, window,
|
||||
ann_data[y].x, ann_data[y].y,
|
||||
ann_data[y].w, ann_data[y].h,
|
||||
False /* No exposures */
|
||||
);
|
||||
}
|
||||
else {
|
||||
XClearArea( display, window, ann_data[ y ].x, ann_data[ y ].y, ann_data[ y ].w, ann_data[ y ].h, False /* No exposures */
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush display */
|
||||
XFlush(display);
|
||||
/* Flush display */
|
||||
XFlush( display );
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RefreshLcd
|
||||
|
@ -608,21 +518,21 @@ void DrawLcd(void)
|
|||
This function refreshes the Lcd screen after a X Window Expose event.
|
||||
|
||||
.call :
|
||||
RefreshLcd();
|
||||
RefreshLcd();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
X11_I_CALLED
|
||||
.notes :
|
||||
1.1, 17-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void RefreshLcd(void)
|
||||
void RefreshLcd( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, X11_I_CALLED, "RefreshLcd");
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "RefreshLcd" );
|
||||
|
||||
ClearLcd();
|
||||
DrawLcd();
|
||||
ClearLcd();
|
||||
DrawLcd();
|
||||
}
|
||||
|
|
|
@ -66,28 +66,23 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Data type definitions - require config.h, machdep.h, cpu.h
|
||||
Data type definitions - require config.h, machdep.h, cpu.h
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macros
|
||||
Macros
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Global variables
|
||||
Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
void InitLcd(Display *lcd_display, Window lcd_window,
|
||||
unsigned long lcd_fg_pixel, unsigned long lcd_bg_pixel);
|
||||
void InitLcd( Display* lcd_display, Window lcd_window, unsigned long lcd_fg_pixel, unsigned long lcd_bg_pixel );
|
||||
|
||||
void DrawLcd(void);
|
||||
void RefreshLcd(void);
|
||||
void DrawLcd( void );
|
||||
void RefreshLcd( void );
|
||||
|
|
653
src/emulator.c
653
src/emulator.c
|
@ -130,17 +130,16 @@ static char rcs_id[] = "$Id: emulator.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
|||
#include "args.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID CPU_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID CPU_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private macros / variables / functions
|
||||
Private macros / variables / functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define T1_MULTIPLIER (8192/16) /* T2/T1 increment ratio */
|
||||
#define T1_INTERVAL 62500 /* us per T1 increment */
|
||||
#define T2_INTERVAL 122 /* us per T2 increment */
|
||||
#define T1_MULTIPLIER ( 8192 / 16 ) /* T2/T1 increment ratio */
|
||||
#define T1_INTERVAL 62500 /* us per T1 increment */
|
||||
#define T2_INTERVAL 122 /* us per T2 increment */
|
||||
|
||||
/* 3.1: MAX_IDLE_X_LOOP_TIMEOUT must be low enough to prevent overflow
|
||||
of an int when computing the difference in microseconds between two
|
||||
|
@ -155,383 +154,353 @@ static char rcs_id[] = "$Id: emulator.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
|||
module will support asynchronous selection on pty fd and will
|
||||
be able to interact with the GUI's select mechanism.
|
||||
*/
|
||||
#define T1_MS_MULTIPLIER 63 /* 3.1: Milliseconds per T1 tick (~) */
|
||||
#define T2_MS_DIVISOR 8 /* 3.1: T2 ticks per millisecond (~) */
|
||||
#define MAX_IDLE_X_LOOP_TIMEOUT 1000 /* 3.1: Max timeout for IdleXLoop() */
|
||||
#define T1_MS_MULTIPLIER 63 /* 3.1: Milliseconds per T1 tick (~) */
|
||||
#define T2_MS_DIVISOR 8 /* 3.1: T2 ticks per millisecond (~) */
|
||||
#define MAX_IDLE_X_LOOP_TIMEOUT 1000 /* 3.1: Max timeout for IdleXLoop() */
|
||||
|
||||
#define T1_OVF_MASK NIBBLE_MASK /* 3.1: Timer overflow masks */
|
||||
#define T2_OVF_MASK 0xFFFFFFFF
|
||||
#define T1_OVF_MASK NIBBLE_MASK /* 3.1: Timer overflow masks */
|
||||
#define T2_OVF_MASK 0xFFFFFFFF
|
||||
|
||||
#define LCD_T1_MASK 0x3 /* LCD refresh timing mask */
|
||||
#define INT_T1_MASK 0xF /* Int. req. timing mask */
|
||||
#define LCD_T1_MASK 0x3 /* LCD refresh timing mask */
|
||||
#define INT_T1_MASK 0xF /* Int. req. timing mask */
|
||||
|
||||
static int emulator_int_req = 0; /* Interrupt request flag */
|
||||
static int emulator_int_req = 0; /* Interrupt request flag */
|
||||
|
||||
/* This function contains the main emulator loop; under normal conditions,
|
||||
it never returns to the caller. The only way to exit this function is
|
||||
to signal a Chf condition that triggers an unwind operation.
|
||||
*/
|
||||
static void EmulatorLoop(void)
|
||||
static void EmulatorLoop( void )
|
||||
{
|
||||
struct timeval old_t, cur_t;
|
||||
int ela;
|
||||
int inner_loop = cpu_status.inner_loop;
|
||||
int t1_count = 0;
|
||||
int i, j;
|
||||
struct timeval old_t, cur_t;
|
||||
int ela;
|
||||
int inner_loop = cpu_status.inner_loop;
|
||||
int t1_count = 0;
|
||||
int i, j;
|
||||
|
||||
debug1(DEBUG_C_TRACE, CPU_I_CALLED, "EmulatorLoop");
|
||||
debug1( DEBUG_C_TRACE, CPU_I_CALLED, "EmulatorLoop" );
|
||||
|
||||
/* Ignore past interrupt requests */
|
||||
emulator_int_req = 0;
|
||||
/* Ignore past interrupt requests */
|
||||
emulator_int_req = 0;
|
||||
|
||||
/* Get current time of day */
|
||||
gettimeofday(&old_t, NULL);
|
||||
/* Get current time of day */
|
||||
gettimeofday( &old_t, NULL );
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* T1 loop */
|
||||
for(j=0; j<T1_MULTIPLIER; j++)
|
||||
{
|
||||
/* Inner loop */
|
||||
for(i=0; i<inner_loop; i++) OneStep();
|
||||
while ( 1 ) {
|
||||
/* T1 loop */
|
||||
for ( j = 0; j < T1_MULTIPLIER; j++ ) {
|
||||
/* Inner loop */
|
||||
for ( i = 0; i < inner_loop; i++ )
|
||||
OneStep();
|
||||
|
||||
/* T2 update */
|
||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_TRUN)
|
||||
{
|
||||
if(--mod_status.hdw.t2_val == 0xFFFFFFFF)
|
||||
{
|
||||
debug1(DEBUG_C_TIMERS, CPU_I_TIMER2_EX, mod_status.hdw.t2_ctrl);
|
||||
/* T2 update */
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) {
|
||||
if ( --mod_status.hdw.t2_val == 0xFFFFFFFF ) {
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_TIMER2_EX, mod_status.hdw.t2_ctrl );
|
||||
|
||||
mod_status.hdw.t2_ctrl |= T2_CTRL_SREQ;
|
||||
mod_status.hdw.t2_ctrl |= T2_CTRL_SREQ;
|
||||
|
||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_WAKE)
|
||||
CpuWake();
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_INT)
|
||||
CpuIntRequest(INT_REQUEST_IRQ);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* T1 update */
|
||||
mod_status.hdw.t1_val = (mod_status.hdw.t1_val - 1) & NIBBLE_MASK;
|
||||
if(mod_status.hdw.t1_val == 0xF)
|
||||
{
|
||||
debug1(DEBUG_C_TIMERS, CPU_I_TIMER1_EX, mod_status.hdw.t1_ctrl);
|
||||
/* T1 update */
|
||||
mod_status.hdw.t1_val = ( mod_status.hdw.t1_val - 1 ) & NIBBLE_MASK;
|
||||
if ( mod_status.hdw.t1_val == 0xF ) {
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_TIMER1_EX, mod_status.hdw.t1_ctrl );
|
||||
|
||||
mod_status.hdw.t1_ctrl |= T1_CTRL_SREQ;
|
||||
mod_status.hdw.t1_ctrl |= T1_CTRL_SREQ;
|
||||
|
||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_WAKE)
|
||||
CpuWake();
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_INT)
|
||||
CpuIntRequest(INT_REQUEST_IRQ);
|
||||
}
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
/* LCD update */
|
||||
if((t1_count++ & LCD_T1_MASK) == 0) DrawLcd();
|
||||
/* LCD update */
|
||||
if ( ( t1_count++ & LCD_T1_MASK ) == 0 )
|
||||
DrawLcd();
|
||||
|
||||
/* Emulator Interrupt Request */
|
||||
if((t1_count & INT_T1_MASK) == 0 && emulator_int_req)
|
||||
{
|
||||
ChfCondition CPU_I_EMULATOR_INT, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
/* Emulator Interrupt Request */
|
||||
if ( ( t1_count & INT_T1_MASK ) == 0 && emulator_int_req ) {
|
||||
ChfCondition CPU_I_EMULATOR_INT, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* X Events handling */
|
||||
HandleXEvents();
|
||||
/* X Events handling */
|
||||
HandleXEvents();
|
||||
|
||||
/* Handle serial port */
|
||||
HandleSerial();
|
||||
/* Handle serial port */
|
||||
HandleSerial();
|
||||
|
||||
/* Adjust inner_loop limit */
|
||||
gettimeofday(&cur_t, NULL);
|
||||
/* Adjust inner_loop limit */
|
||||
gettimeofday( &cur_t, NULL );
|
||||
|
||||
ela = (cur_t.tv_sec - old_t.tv_sec) * 1000000 +
|
||||
(cur_t.tv_usec - old_t.tv_usec);
|
||||
|
||||
inner_loop = inner_loop * T1_INTERVAL / ela;
|
||||
if(inner_loop < INNER_LOOP_MIN) inner_loop = INNER_LOOP_MIN;
|
||||
ela = ( cur_t.tv_sec - old_t.tv_sec ) * 1000000 + ( cur_t.tv_usec - old_t.tv_usec );
|
||||
|
||||
inner_loop = inner_loop * T1_INTERVAL / ela;
|
||||
if ( inner_loop < INNER_LOOP_MIN )
|
||||
inner_loop = INNER_LOOP_MIN;
|
||||
|
||||
#ifdef REAL_CPU_SPEED
|
||||
/* 3.13: Force an upper limit to the CPU speed if the compile-time option
|
||||
REAL_CPU_SPEED is defined: inner_loop is limited to
|
||||
cpu_status.inner_loop_max
|
||||
and the excess time, if any, is spent sleeping; usleep() is
|
||||
BSD 4.3-specific, but most recent systems should offer it anyway,
|
||||
well, I hope.
|
||||
The special value cpu_status.inner_loop_max==0 gives maximum speed.
|
||||
*/
|
||||
if(cpu_status.inner_loop_max != 0
|
||||
&& inner_loop >= cpu_status.inner_loop_max)
|
||||
{
|
||||
inner_loop = cpu_status.inner_loop_max;
|
||||
if(T1_INTERVAL > ela) usleep(T1_INTERVAL - ela);
|
||||
}
|
||||
/* 3.13: Force an upper limit to the CPU speed if the compile-time option
|
||||
REAL_CPU_SPEED is defined: inner_loop is limited to
|
||||
cpu_status.inner_loop_max
|
||||
and the excess time, if any, is spent sleeping; usleep() is
|
||||
BSD 4.3-specific, but most recent systems should offer it anyway,
|
||||
well, I hope.
|
||||
The special value cpu_status.inner_loop_max==0 gives maximum speed.
|
||||
*/
|
||||
if ( cpu_status.inner_loop_max != 0 && inner_loop >= cpu_status.inner_loop_max ) {
|
||||
inner_loop = cpu_status.inner_loop_max;
|
||||
if ( T1_INTERVAL > ela )
|
||||
usleep( T1_INTERVAL - ela );
|
||||
}
|
||||
#endif
|
||||
|
||||
cpu_status.inner_loop = inner_loop;
|
||||
old_t = cur_t;
|
||||
}
|
||||
cpu_status.inner_loop = inner_loop;
|
||||
old_t = cur_t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Condition handler for the EmulatorLoop */
|
||||
static ChfAction EmulatorLoopHandler(
|
||||
const ChfDescriptor *d,
|
||||
const ChfState s,
|
||||
ChfPointer ctx
|
||||
)
|
||||
static ChfAction EmulatorLoopHandler( const ChfDescriptor* d, const ChfState s, ChfPointer ctx )
|
||||
{
|
||||
ChfAction act;
|
||||
ChfAction act;
|
||||
|
||||
/* Check Chf state */
|
||||
switch(s)
|
||||
{
|
||||
/* 2.1: Chf release 2 fixed the spelling of 'SIGNALING' */
|
||||
case CHF_SIGNALING:
|
||||
/* ChfSignal() in progress */
|
||||
if(ChfGetModuleId(d) == CPU_CHF_MODULE_ID)
|
||||
{
|
||||
/* Condition from CPU modules; check Condition Code */
|
||||
switch(ChfGetConditionCode(d))
|
||||
{
|
||||
/* Check Chf state */
|
||||
switch ( s ) {
|
||||
/* 2.1: Chf release 2 fixed the spelling of 'SIGNALING' */
|
||||
case CHF_SIGNALING:
|
||||
/* ChfSignal() in progress */
|
||||
if ( ChfGetModuleId( d ) == CPU_CHF_MODULE_ID ) {
|
||||
/* Condition from CPU modules; check Condition Code */
|
||||
switch ( ChfGetConditionCode( d ) ) {
|
||||
#ifdef CPU_SPIN_SHUTDN
|
||||
case CPU_I_SHUTDN:
|
||||
/* CPU shutdown signalled with CPU_SPIN_SHUTDN defined;
|
||||
Fatal error.
|
||||
*/
|
||||
ChfCondition CPU_F_BAD_SHUTDN, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
case CPU_I_SHUTDN:
|
||||
/* CPU shutdown signalled with CPU_SPIN_SHUTDN defined;
|
||||
Fatal error.
|
||||
*/
|
||||
ChfCondition CPU_F_BAD_SHUTDN, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
act = CHF_RESIGNAL;
|
||||
break;
|
||||
act = CHF_RESIGNAL;
|
||||
break;
|
||||
#else
|
||||
case CPU_I_SHUTDN:
|
||||
{
|
||||
/* 3.1: CPU_SPIN_SHUTDN is not defined, and the cpu emulator
|
||||
has just executed a shutdown instruction.
|
||||
Let's do something a little tricky here:
|
||||
case CPU_I_SHUTDN:
|
||||
{
|
||||
/* 3.1: CPU_SPIN_SHUTDN is not defined, and the cpu emulator
|
||||
has just executed a shutdown instruction.
|
||||
Let's do something a little tricky here:
|
||||
|
||||
1- redraw the LCD
|
||||
1- redraw the LCD
|
||||
|
||||
2- handle serial port activities
|
||||
2- handle serial port activities
|
||||
|
||||
3- determine which timer will expire first, and
|
||||
compute an approximate value of the maximum duration
|
||||
of the shutdown --> ms
|
||||
3- determine which timer will expire first, and
|
||||
compute an approximate value of the maximum duration
|
||||
of the shutdown --> ms
|
||||
|
||||
4- handle serial port activities
|
||||
4- handle serial port activities
|
||||
|
||||
5- enter the inner idle loop; it breaks when either an
|
||||
X Event occurred (possibly clearing the shutdown) or
|
||||
the shutdown timeout elapses
|
||||
5- enter the inner idle loop; it breaks when either an
|
||||
X Event occurred (possibly clearing the shutdown) or
|
||||
the shutdown timeout elapses
|
||||
|
||||
6- determine the actual time we spend in the idle loop
|
||||
(X timeouts are not accurate enough for this purpose)
|
||||
6- determine the actual time we spend in the idle loop
|
||||
(X timeouts are not accurate enough for this purpose)
|
||||
|
||||
7- update T1 and T2, check their state and wake/interrupt
|
||||
the CPU if necessary
|
||||
7- update T1 and T2, check their state and wake/interrupt
|
||||
the CPU if necessary
|
||||
|
||||
Activities 3-7 above are enclosed in an outer loop because we
|
||||
cannot be absolutely sure of the actual time spent
|
||||
in the idle loop; moreover, not all X Events actually
|
||||
spool up the CPU. The outer loop breaks when the CPU is
|
||||
actually brought out of shutdown.
|
||||
Activities 3-7 above are enclosed in an outer loop because we
|
||||
cannot be absolutely sure of the actual time spent
|
||||
in the idle loop; moreover, not all X Events actually
|
||||
spool up the CPU. The outer loop breaks when the CPU is
|
||||
actually brought out of shutdown.
|
||||
|
||||
frac_t1 and frac_t2 contain the number of microseconds
|
||||
not accounted for in the last T1/T2 update, respectively;
|
||||
they help minimize the cumulative timing error induced
|
||||
by executing the outer idle loop more than once.
|
||||
*/
|
||||
struct timeval start_idle, end_idle;
|
||||
int frac_t1=0, frac_t2=0;
|
||||
frac_t1 and frac_t2 contain the number of microseconds
|
||||
not accounted for in the last T1/T2 update, respectively;
|
||||
they help minimize the cumulative timing error induced
|
||||
by executing the outer idle loop more than once.
|
||||
*/
|
||||
struct timeval start_idle, end_idle;
|
||||
int frac_t1 = 0, frac_t2 = 0;
|
||||
|
||||
gettimeofday(&start_idle, NULL);
|
||||
gettimeofday( &start_idle, NULL );
|
||||
|
||||
/* Redraw the LCD immediately before entering idle loop;
|
||||
this ensures that the latest LCD updated actually
|
||||
get to the screen.
|
||||
*/
|
||||
DrawLcd();
|
||||
/* Redraw the LCD immediately before entering idle loop;
|
||||
this ensures that the latest LCD updated actually
|
||||
get to the screen.
|
||||
*/
|
||||
DrawLcd();
|
||||
|
||||
/* Handle serial port activity before entering the outer idle
|
||||
loop, because this could possibly bring the cpu out of
|
||||
shutdown right now.
|
||||
*/
|
||||
HandleSerial();
|
||||
/* Handle serial port activity before entering the outer idle
|
||||
loop, because this could possibly bring the cpu out of
|
||||
shutdown right now.
|
||||
*/
|
||||
HandleSerial();
|
||||
|
||||
/* XXX
|
||||
If either timer has a pending service request,
|
||||
process it immediately. It is not clear why it was
|
||||
not processed *before* shutdown, though.
|
||||
*/
|
||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_SREQ)
|
||||
{
|
||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_WAKE)
|
||||
CpuWake();
|
||||
/* XXX
|
||||
If either timer has a pending service request,
|
||||
process it immediately. It is not clear why it was
|
||||
not processed *before* shutdown, though.
|
||||
*/
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_SREQ ) {
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_INT)
|
||||
CpuIntRequest(INT_REQUEST_IRQ);
|
||||
}
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_SREQ)
|
||||
{
|
||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_WAKE)
|
||||
CpuWake();
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_SREQ ) {
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_INT)
|
||||
CpuIntRequest(INT_REQUEST_IRQ);
|
||||
}
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
while(cpu_status.shutdn)
|
||||
{
|
||||
unsigned long ms = MAX_IDLE_X_LOOP_TIMEOUT;
|
||||
unsigned long mst;
|
||||
int ela;
|
||||
int ela_ticks;
|
||||
while ( cpu_status.shutdn ) {
|
||||
unsigned long ms = MAX_IDLE_X_LOOP_TIMEOUT;
|
||||
unsigned long mst;
|
||||
int ela;
|
||||
int ela_ticks;
|
||||
|
||||
debug3(DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (during SHUTDN)",
|
||||
mod_status.hdw.t1_ctrl, mod_status.hdw.t1_val);
|
||||
debug3(DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T2 (during SHUTDN)",
|
||||
mod_status.hdw.t2_ctrl, mod_status.hdw.t2_val);
|
||||
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (during SHUTDN)", mod_status.hdw.t1_ctrl,
|
||||
mod_status.hdw.t1_val );
|
||||
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T2 (during SHUTDN)", mod_status.hdw.t2_ctrl,
|
||||
mod_status.hdw.t2_val );
|
||||
|
||||
/* Determine which timer will expire first */
|
||||
if(mod_status.hdw.t1_ctrl & (T1_CTRL_INT|T1_CTRL_WAKE))
|
||||
{
|
||||
/* T1 will do something on expiration */
|
||||
mst = ((unsigned long)mod_status.hdw.t1_val + 1)
|
||||
* T1_MS_MULTIPLIER;
|
||||
/* Determine which timer will expire first */
|
||||
if ( mod_status.hdw.t1_ctrl & ( T1_CTRL_INT | T1_CTRL_WAKE ) ) {
|
||||
/* T1 will do something on expiration */
|
||||
mst = ( ( unsigned long )mod_status.hdw.t1_val + 1 ) * T1_MS_MULTIPLIER;
|
||||
|
||||
debug2(DEBUG_C_TIMERS, CPU_I_TIMER_EXP, "T1", mst);
|
||||
debug2( DEBUG_C_TIMERS, CPU_I_TIMER_EXP, "T1", mst );
|
||||
|
||||
if(mst < ms) ms = mst;
|
||||
}
|
||||
if ( mst < ms )
|
||||
ms = mst;
|
||||
}
|
||||
|
||||
if((mod_status.hdw.t2_ctrl & T2_CTRL_TRUN)
|
||||
&& (mod_status.hdw.t2_ctrl & (T2_CTRL_INT|T2_CTRL_WAKE)))
|
||||
{
|
||||
/* T2 is running and will do something on expiration */
|
||||
mst = ((unsigned long)mod_status.hdw.t2_val + 1)
|
||||
/ T2_MS_DIVISOR;
|
||||
if ( ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) &&
|
||||
( mod_status.hdw.t2_ctrl & ( T2_CTRL_INT | T2_CTRL_WAKE ) ) ) {
|
||||
/* T2 is running and will do something on expiration */
|
||||
mst = ( ( unsigned long )mod_status.hdw.t2_val + 1 ) / T2_MS_DIVISOR;
|
||||
|
||||
debug2(DEBUG_C_TIMERS, CPU_I_TIMER_EXP, "T2", mst);
|
||||
debug2( DEBUG_C_TIMERS, CPU_I_TIMER_EXP, "T2", mst );
|
||||
|
||||
if(mst < ms) ms = mst;
|
||||
}
|
||||
if ( mst < ms )
|
||||
ms = mst;
|
||||
}
|
||||
|
||||
/* Handle serial port activities at each iteration of
|
||||
the outer idle loop; this ensures that the serial
|
||||
port emulation will not starve.
|
||||
*/
|
||||
HandleSerial();
|
||||
/* Handle serial port activities at each iteration of
|
||||
the outer idle loop; this ensures that the serial
|
||||
port emulation will not starve.
|
||||
*/
|
||||
HandleSerial();
|
||||
|
||||
/* Enter idle loop, possibly with timeout;
|
||||
The loop breaks when:
|
||||
- any X Event occurs (possibly clearing the shutdown)
|
||||
- the given timeout expires
|
||||
*/
|
||||
debug1(DEBUG_C_TIMERS, CPU_I_IDLE_X_LOOP, ms);
|
||||
IdleXLoop(ms);
|
||||
/* Enter idle loop, possibly with timeout;
|
||||
The loop breaks when:
|
||||
- any X Event occurs (possibly clearing the shutdown)
|
||||
- the given timeout expires
|
||||
*/
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_IDLE_X_LOOP, ms );
|
||||
IdleXLoop( ms );
|
||||
|
||||
/* End of idle loop; compute actual elapsed time */
|
||||
gettimeofday(&end_idle, NULL);
|
||||
/* End of idle loop; compute actual elapsed time */
|
||||
gettimeofday( &end_idle, NULL );
|
||||
|
||||
ela = (end_idle.tv_sec - start_idle.tv_sec) * 1000000 +
|
||||
(end_idle.tv_usec - start_idle.tv_usec);
|
||||
ela = ( end_idle.tv_sec - start_idle.tv_sec ) * 1000000 + ( end_idle.tv_usec - start_idle.tv_usec );
|
||||
|
||||
/* Update start_idle here to contain lag */
|
||||
start_idle = end_idle;
|
||||
/* Update start_idle here to contain lag */
|
||||
start_idle = end_idle;
|
||||
|
||||
debug1(DEBUG_C_TIMERS, CPU_I_ELAPSED, ela);
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_ELAPSED, ela );
|
||||
|
||||
/* Update timers and act accordingly */
|
||||
ela_ticks = ((ela+frac_t1) + T1_INTERVAL/2) / T1_INTERVAL;
|
||||
frac_t1 = (ela+frac_t1) - ela_ticks * T1_INTERVAL;
|
||||
/* Update timers and act accordingly */
|
||||
ela_ticks = ( ( ela + frac_t1 ) + T1_INTERVAL / 2 ) / T1_INTERVAL;
|
||||
frac_t1 = ( ela + frac_t1 ) - ela_ticks * T1_INTERVAL;
|
||||
|
||||
if(ela_ticks > mod_status.hdw.t1_val)
|
||||
{
|
||||
debug1(DEBUG_C_TIMERS, CPU_I_TIMER1_EX,
|
||||
mod_status.hdw.t1_ctrl);
|
||||
if ( ela_ticks > mod_status.hdw.t1_val ) {
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_TIMER1_EX, mod_status.hdw.t1_ctrl );
|
||||
|
||||
mod_status.hdw.t1_ctrl |= T1_CTRL_SREQ;
|
||||
mod_status.hdw.t1_ctrl |= T1_CTRL_SREQ;
|
||||
|
||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_WAKE)
|
||||
CpuWake();
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_INT)
|
||||
CpuIntRequest(INT_REQUEST_IRQ);
|
||||
}
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
mod_status.hdw.t1_val =
|
||||
(mod_status.hdw.t1_val - ela_ticks) & T1_OVF_MASK;
|
||||
mod_status.hdw.t1_val = ( mod_status.hdw.t1_val - ela_ticks ) & T1_OVF_MASK;
|
||||
|
||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_TRUN)
|
||||
{
|
||||
ela_ticks = ((ela+frac_t2) + T2_INTERVAL/2) / T2_INTERVAL;
|
||||
frac_t2 = (ela+frac_t2) - ela_ticks * T2_INTERVAL;
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) {
|
||||
ela_ticks = ( ( ela + frac_t2 ) + T2_INTERVAL / 2 ) / T2_INTERVAL;
|
||||
frac_t2 = ( ela + frac_t2 ) - ela_ticks * T2_INTERVAL;
|
||||
|
||||
if(ela_ticks > mod_status.hdw.t2_val)
|
||||
{
|
||||
debug1(DEBUG_C_TIMERS, CPU_I_TIMER2_EX,
|
||||
mod_status.hdw.t2_ctrl);
|
||||
if ( ela_ticks > mod_status.hdw.t2_val ) {
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_TIMER2_EX, mod_status.hdw.t2_ctrl );
|
||||
|
||||
mod_status.hdw.t2_ctrl |= T2_CTRL_SREQ;
|
||||
mod_status.hdw.t2_ctrl |= T2_CTRL_SREQ;
|
||||
|
||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_WAKE)
|
||||
CpuWake();
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_INT)
|
||||
CpuIntRequest(INT_REQUEST_IRQ);
|
||||
}
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
mod_status.hdw.t2_val =
|
||||
(mod_status.hdw.t2_val - ela_ticks) & T2_OVF_MASK;
|
||||
}
|
||||
}
|
||||
mod_status.hdw.t2_val = ( mod_status.hdw.t2_val - ela_ticks ) & T2_OVF_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
debug3(DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (after SHUTDN)",
|
||||
mod_status.hdw.t1_ctrl, mod_status.hdw.t1_val);
|
||||
debug3(DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T2 (after SHUTDN)",
|
||||
mod_status.hdw.t2_ctrl, mod_status.hdw.t2_val);
|
||||
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (after SHUTDN)", mod_status.hdw.t1_ctrl, mod_status.hdw.t1_val );
|
||||
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T2 (after SHUTDN)", mod_status.hdw.t2_ctrl, mod_status.hdw.t2_val );
|
||||
|
||||
act = CHF_CONTINUE;
|
||||
}
|
||||
break;
|
||||
act = CHF_CONTINUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CPU_I_EMULATOR_INT:
|
||||
/* Emulator interrupt; unwind */
|
||||
act = CHF_UNWIND;
|
||||
break;
|
||||
case CPU_I_EMULATOR_INT:
|
||||
/* Emulator interrupt; unwind */
|
||||
act = CHF_UNWIND;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Condition Code not handled; resignal */
|
||||
act = CHF_RESIGNAL;
|
||||
}
|
||||
}
|
||||
default:
|
||||
/* Condition Code not handled; resignal */
|
||||
act = CHF_RESIGNAL;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
/* Condition from other modules; resignal */
|
||||
act = CHF_RESIGNAL;
|
||||
else
|
||||
/* Condition from other modules; resignal */
|
||||
act = CHF_RESIGNAL;
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Other states; resignal the condition */
|
||||
act = CHF_RESIGNAL;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Other states; resignal the condition */
|
||||
act = CHF_RESIGNAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return act;
|
||||
return act;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Emulator
|
||||
|
@ -547,43 +516,40 @@ static ChfAction EmulatorLoopHandler(
|
|||
a Chf Condition that triggers an unwind operation.
|
||||
|
||||
.call :
|
||||
Emulator();
|
||||
Emulator();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
CPU_I_CALLED
|
||||
CPU_I_TIMER1_EX
|
||||
CPU_I_TIMER2_EX
|
||||
Other conditions signalled by lower level modules
|
||||
CPU_I_CALLED
|
||||
CPU_I_TIMER1_EX
|
||||
CPU_I_TIMER2_EX
|
||||
Other conditions signalled by lower level modules
|
||||
.notes :
|
||||
1.1, 17-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void Emulator(void)
|
||||
void Emulator( void )
|
||||
{
|
||||
jmp_buf unwind_context;
|
||||
jmp_buf unwind_context;
|
||||
|
||||
debug1(DEBUG_C_TRACE, CPU_I_CALLED, "Emulator");
|
||||
debug1( DEBUG_C_TRACE, CPU_I_CALLED, "Emulator" );
|
||||
|
||||
/* Setup unwind_context */
|
||||
if(setjmp(unwind_context) == 0)
|
||||
{
|
||||
/* Push condition handler, with NULL context */
|
||||
ChfPushHandler(EmulatorLoopHandler, &unwind_context, (ChfPointer)NULL);
|
||||
/* Setup unwind_context */
|
||||
if ( setjmp( unwind_context ) == 0 ) {
|
||||
/* Push condition handler, with NULL context */
|
||||
ChfPushHandler( EmulatorLoopHandler, &unwind_context, ( ChfPointer )NULL );
|
||||
|
||||
/* Activate emulator loop */
|
||||
EmulatorLoop();
|
||||
}
|
||||
/* Activate emulator loop */
|
||||
EmulatorLoop();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Unwinding after an emulator interrupt */
|
||||
}
|
||||
else {
|
||||
/* Unwinding after an emulator interrupt */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : EmulatorIntRequest
|
||||
|
@ -595,22 +561,18 @@ void Emulator(void)
|
|||
return to the caller.
|
||||
|
||||
.call :
|
||||
EmulatorIntRequest();
|
||||
EmulatorIntRequest();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
*
|
||||
*
|
||||
.notes :
|
||||
1.1, 18-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void EmulatorIntRequest(void)
|
||||
{
|
||||
emulator_int_req = 1;
|
||||
}
|
||||
|
||||
void EmulatorIntRequest( void ) { emulator_int_req = 1; }
|
||||
|
||||
/* .+
|
||||
|
||||
|
@ -623,14 +585,14 @@ void EmulatorIntRequest(void)
|
|||
subsystems, too.
|
||||
|
||||
.call :
|
||||
EmulatorInit();
|
||||
EmulatorInit();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
* Status codes signaled by CpuInit() and CpuReset()
|
||||
* Status codes signaled by ModInit() and ModReset()
|
||||
* Status codes signaled by CpuInit() and CpuReset()
|
||||
* Status codes signaled by ModInit() and ModReset()
|
||||
.notes :
|
||||
2.1, 8-Sep-2000, creation
|
||||
2.4, 12-Sep-2000, update
|
||||
|
@ -642,24 +604,22 @@ void EmulatorIntRequest(void)
|
|||
args.hw option.
|
||||
|
||||
.- */
|
||||
void EmulatorInit(void)
|
||||
void EmulatorInit( void )
|
||||
{
|
||||
/* Select a module description table */
|
||||
ModSelectDescription(args.hw);
|
||||
ModSelectDescription( args.hw );
|
||||
|
||||
/* Initialize cpu and modules subsystems */
|
||||
CpuInit();
|
||||
ModInit();
|
||||
|
||||
/* Reset if appropriate */
|
||||
if(args.reset)
|
||||
{
|
||||
CpuReset();
|
||||
ModReset();
|
||||
if ( args.reset ) {
|
||||
CpuReset();
|
||||
ModReset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : EmulatorExit
|
||||
|
@ -672,30 +632,29 @@ void EmulatorInit(void)
|
|||
returns to the caller unless an unrecoverable error occurs.
|
||||
|
||||
.call :
|
||||
EmulatorExit(opt);
|
||||
EmulatorExit(opt);
|
||||
.input :
|
||||
enum ExitOption opt, emulator exit option
|
||||
enum ExitOption opt, emulator exit option
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
* Status codes signaled by CpuSave() and ModSave()
|
||||
* Status codes signaled by CpuSave() and ModSave()
|
||||
.notes :
|
||||
2.1, 8-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void EmulatorExit(enum ExitOption opt)
|
||||
void EmulatorExit( enum ExitOption opt )
|
||||
{
|
||||
switch(opt)
|
||||
{
|
||||
switch ( opt ) {
|
||||
|
||||
case SAVE_AND_EXIT:
|
||||
/* Save state of cpu and modules subsystems */
|
||||
ModSave();
|
||||
CpuSave();
|
||||
break;
|
||||
case SAVE_AND_EXIT:
|
||||
/* Save state of cpu and modules subsystems */
|
||||
ModSave();
|
||||
CpuSave();
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Default behavior; do nothing */
|
||||
break;
|
||||
default:
|
||||
/* Default behavior; do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
392
src/flash49.c
392
src/flash49.c
|
@ -87,326 +87,273 @@ static char rcs_id[] = "$Id: flash49.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $"
|
|||
|
||||
#include "args.h"
|
||||
|
||||
#define CHF_MODULE_ID FLASH_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID FLASH_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private Macro/Data type definitions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define BLOCK_SIZE 0x10000
|
||||
#define BLOCK_BASE_MASK 0xFFFF
|
||||
|
||||
#define ByteAddress(address) ((address) >> 1)
|
||||
#define NibbleAddress(address) ((address) << 1)
|
||||
#define BlockBase(address) ((address) & ~BLOCK_BASE_MASK)
|
||||
#define IsOdd(address) ((address) & 0x1)
|
||||
#define LowNibble(d) ((Nibble)((d) & NIBBLE_MASK))
|
||||
#define HighNibble(d) ((Nibble)(((d) >> 4) & NIBBLE_MASK))
|
||||
#define ShiftHigh(d) ((d) << 4)
|
||||
#define BLOCK_SIZE 0x10000
|
||||
#define BLOCK_BASE_MASK 0xFFFF
|
||||
|
||||
#define ByteAddress( address ) ( ( address ) >> 1 )
|
||||
#define NibbleAddress( address ) ( ( address ) << 1 )
|
||||
#define BlockBase( address ) ( ( address ) & ~BLOCK_BASE_MASK )
|
||||
#define IsOdd( address ) ( ( address ) & 0x1 )
|
||||
#define LowNibble( d ) ( ( Nibble )( ( d ) & NIBBLE_MASK ) )
|
||||
#define HighNibble( d ) ( ( Nibble )( ( ( d ) >> 4 ) & NIBBLE_MASK ) )
|
||||
#define ShiftHigh( d ) ( ( d ) << 4 )
|
||||
|
||||
/* Flash cycle types */
|
||||
enum FlashCycle
|
||||
{
|
||||
enum FlashCycle {
|
||||
FLASH_CYCLE_READ = 0,
|
||||
FLASH_CYCLE_WRITE,
|
||||
|
||||
FLASH_CYCLE_N /* Total # of cycle types */
|
||||
FLASH_CYCLE_N /* Total # of cycle types */
|
||||
};
|
||||
|
||||
/* State transition function */
|
||||
typedef int (*FlashF)
|
||||
(enum FlashState *state, enum FlashCycle cycle,
|
||||
XAddress address, int data);
|
||||
|
||||
|
||||
typedef int ( *FlashF )( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data );
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private state variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* External storage */
|
||||
extern struct ModStatus_49 *mod_status_49;
|
||||
extern struct ModStatus_49* mod_status_49;
|
||||
|
||||
static int r_buffer; /* Nibble buffer during read */
|
||||
static int w_buffer; /* Nibble buffer during write */
|
||||
static enum FlashState fsm_state; /* FSM state */
|
||||
static int r_buffer; /* Nibble buffer during read */
|
||||
static int w_buffer; /* Nibble buffer during write */
|
||||
static enum FlashState fsm_state; /* FSM state */
|
||||
|
||||
/* Write buffer */
|
||||
#define WB_COUNT_MASK 0x1F
|
||||
#define WB_SIZE 0x20
|
||||
static int wb_count; /* Counter for Write to Buffer */
|
||||
static int wb_cdown; /* Count down */
|
||||
static XAddress wb_start; /* Start address for Write to Buffer */
|
||||
static int wb[WB_SIZE]; /* Write buffer */
|
||||
|
||||
|
||||
#define WB_COUNT_MASK 0x1F
|
||||
#define WB_SIZE 0x20
|
||||
static int wb_count; /* Counter for Write to Buffer */
|
||||
static int wb_cdown; /* Count down */
|
||||
static XAddress wb_start; /* Start address for Write to Buffer */
|
||||
static int wb[ WB_SIZE ]; /* Write buffer */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
State transition private functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* This function is called by default for unhandled state transitions */
|
||||
static int BadCommand(enum FlashState *state, enum FlashCycle cycle,
|
||||
XAddress address, int data)
|
||||
static int BadCommand( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
/* Unknown command: signal and reset state to FLASH_ST_READ_ARRAY */
|
||||
ChfCondition FLASH_W_BAD_CMD, CHF_WARNING,
|
||||
*state, cycle, address, data
|
||||
ChfEnd;
|
||||
ChfCondition FLASH_W_BAD_CMD, CHF_WARNING, *state, cycle, address, data ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
*state = FLASH_ST_READ_ARRAY;
|
||||
return 0; /* Dummy result */
|
||||
return 0; /* Dummy result */
|
||||
}
|
||||
|
||||
|
||||
/* This function is called to read the Flash Rom array */
|
||||
static int ReadArray(enum FlashState *state, enum FlashCycle cycle,
|
||||
XAddress address, int data)
|
||||
static int ReadArray( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
/* Read a byte from the array; no state transitions */
|
||||
return
|
||||
mod_status_49->flash[NibbleAddress(address)]
|
||||
| ShiftHigh(mod_status_49->flash[NibbleAddress(address)+1]);
|
||||
return mod_status_49->flash[ NibbleAddress( address ) ] | ShiftHigh( mod_status_49->flash[ NibbleAddress( address ) + 1 ] );
|
||||
}
|
||||
|
||||
|
||||
/* This function is called to parse the first byte of any command */
|
||||
static int ParseCommand(enum FlashState *state, enum FlashCycle cycle,
|
||||
XAddress address, int data)
|
||||
static int ParseCommand( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
switch(data)
|
||||
{
|
||||
case FLASH_CMD_READ_ARRAY:
|
||||
/* Transition to FLASH_ST_READ_ARRAY state */
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Array");
|
||||
*state = FLASH_ST_READ_ARRAY;
|
||||
break;
|
||||
switch ( data ) {
|
||||
case FLASH_CMD_READ_ARRAY:
|
||||
/* Transition to FLASH_ST_READ_ARRAY state */
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Array" );
|
||||
*state = FLASH_ST_READ_ARRAY;
|
||||
break;
|
||||
|
||||
case FLASH_CMD_CLR_SR:
|
||||
/* Clear status register; section 4.5 on Data Sheet.
|
||||
The current implementation does nothing, because
|
||||
the value of the status register is fixed. No state transitions.
|
||||
*/
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Clear Status");
|
||||
break;
|
||||
case FLASH_CMD_CLR_SR:
|
||||
/* Clear status register; section 4.5 on Data Sheet.
|
||||
The current implementation does nothing, because
|
||||
the value of the status register is fixed. No state transitions.
|
||||
*/
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Clear Status" );
|
||||
break;
|
||||
|
||||
case FLASH_CMD_WRITE_BUFFER:
|
||||
/* Write to Buffer; section 4.8 on Data Sheet.
|
||||
Transition to FLASH_ST_READ_XSR state.
|
||||
*/
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (start)");
|
||||
*state = FLASH_ST_READ_XSR;
|
||||
break;
|
||||
case FLASH_CMD_WRITE_BUFFER:
|
||||
/* Write to Buffer; section 4.8 on Data Sheet.
|
||||
Transition to FLASH_ST_READ_XSR state.
|
||||
*/
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (start)" );
|
||||
*state = FLASH_ST_READ_XSR;
|
||||
break;
|
||||
|
||||
case FLASH_CMD_READ_SR:
|
||||
/* Read Status; section 4.4 on Data Sheet.
|
||||
Transition to FLASH_ST_READ_SR state.
|
||||
*/
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Status");
|
||||
*state = FLASH_ST_READ_SR;
|
||||
break;
|
||||
case FLASH_CMD_READ_SR:
|
||||
/* Read Status; section 4.4 on Data Sheet.
|
||||
Transition to FLASH_ST_READ_SR state.
|
||||
*/
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Status" );
|
||||
*state = FLASH_ST_READ_SR;
|
||||
break;
|
||||
|
||||
case FLASH_CMD_BL_ERASE:
|
||||
/* Block Erase; section 4.6 on Data Sheet.
|
||||
Transition to FLASH_ST_BL_ERASE state.
|
||||
Consistency of block addresses is not checked.
|
||||
*/
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Erase Block (start)");
|
||||
*state = FLASH_ST_BL_ERASE;
|
||||
break;
|
||||
case FLASH_CMD_BL_ERASE:
|
||||
/* Block Erase; section 4.6 on Data Sheet.
|
||||
Transition to FLASH_ST_BL_ERASE state.
|
||||
Consistency of block addresses is not checked.
|
||||
*/
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Erase Block (start)" );
|
||||
*state = FLASH_ST_BL_ERASE;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown command; signal, ignore, keep current state. */
|
||||
ChfCondition FLASH_W_BAD_CMD, CHF_WARNING,
|
||||
*state, cycle, address, data
|
||||
ChfEnd;
|
||||
ChfSignal();
|
||||
break;
|
||||
default:
|
||||
/* Unknown command; signal, ignore, keep current state. */
|
||||
ChfCondition FLASH_W_BAD_CMD, CHF_WARNING, *state, cycle, address, data ChfEnd;
|
||||
ChfSignal();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* No result; this is a write cycle */
|
||||
return 0; /* No result; this is a write cycle */
|
||||
}
|
||||
|
||||
|
||||
/* This function returns to the caller the value of XSR */
|
||||
static int ReadXSR(enum FlashState *state, enum FlashCycle cycle,
|
||||
XAddress address, int data)
|
||||
static int ReadXSR( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
/* Return XSR status; a buffer is always available in the current
|
||||
emulation scheme. Keep current state.
|
||||
*/
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read XSR");
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read XSR" );
|
||||
return FLASH_XSR_WBS;
|
||||
}
|
||||
|
||||
|
||||
/* This function returns to the caller the value of SR */
|
||||
static int ReadSR(enum FlashState *state, enum FlashCycle cycle,
|
||||
XAddress address, int data)
|
||||
static int ReadSR( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
/* Return SR status; the WSM executes in zero time in the current
|
||||
emulation scheme. Keep current state.
|
||||
*/
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read SR");
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read SR" );
|
||||
return FLASH_SR_WSMS;
|
||||
}
|
||||
|
||||
|
||||
/* This function is called to store the WRITE_BUFFER byte count;
|
||||
both wb_count and wb_cdown are set; StoreData() decrements the
|
||||
latter, WriteConfirm() uses the former to determine how many bytes
|
||||
must write to the Flash array.
|
||||
*/
|
||||
static int StoreCount(enum FlashState *state, enum FlashCycle cycle,
|
||||
XAddress address, int data)
|
||||
static int StoreCount( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
/* Store WRITE_BUFFER count; next state is FLASH_ST_WRITE_DATA */
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (count)");
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (count)" );
|
||||
wb_count = wb_cdown = data & WB_COUNT_MASK;
|
||||
|
||||
*state = FLASH_ST_WRITE_DATA_1;
|
||||
return 0; /* No result; this is a write cycle */
|
||||
return 0; /* No result; this is a write cycle */
|
||||
}
|
||||
|
||||
|
||||
/* This function is called to store a byte into the write buffer.
|
||||
The first write cycle also sets the buffer's base address (wb_start).
|
||||
The function transitions to state FLASH_ST_WRITE_CONFIRM when all
|
||||
bytes have been stored.
|
||||
*/
|
||||
static int StoreData(enum FlashState *state, enum FlashCycle cycle,
|
||||
XAddress address, int data)
|
||||
static int StoreData( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
int index;
|
||||
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (data)");
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (data)" );
|
||||
|
||||
/* Store WRITE_BUFFER data; the first write also stores the
|
||||
buffer starting address.
|
||||
*/
|
||||
switch(*state)
|
||||
{
|
||||
switch ( *state ) {
|
||||
|
||||
case FLASH_ST_WRITE_DATA_1:
|
||||
wb_start = address;
|
||||
wb[0] = data;
|
||||
*state = FLASH_ST_WRITE_DATA_N;
|
||||
break;
|
||||
case FLASH_ST_WRITE_DATA_1:
|
||||
wb_start = address;
|
||||
wb[ 0 ] = data;
|
||||
*state = FLASH_ST_WRITE_DATA_N;
|
||||
break;
|
||||
|
||||
case FLASH_ST_WRITE_DATA_N:
|
||||
index = address - wb_start;
|
||||
if(index < 0 || index >= WB_SIZE)
|
||||
{
|
||||
ChfCondition FLASH_W_BAD_ADDRESS, CHF_WARNING,
|
||||
*state, cycle, address, data
|
||||
ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
else
|
||||
wb[index] = data;
|
||||
break;
|
||||
case FLASH_ST_WRITE_DATA_N:
|
||||
index = address - wb_start;
|
||||
if ( index < 0 || index >= WB_SIZE ) {
|
||||
ChfCondition FLASH_W_BAD_ADDRESS, CHF_WARNING, *state, cycle, address, data ChfEnd;
|
||||
ChfSignal();
|
||||
} else
|
||||
wb[ index ] = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
*state = FLASH_ST_READ_ARRAY;
|
||||
break;
|
||||
default:
|
||||
*state = FLASH_ST_READ_ARRAY;
|
||||
break;
|
||||
}
|
||||
|
||||
if(--wb_cdown < 0)
|
||||
*state = FLASH_ST_WRITE_CONFIRM;
|
||||
if ( --wb_cdown < 0 )
|
||||
*state = FLASH_ST_WRITE_CONFIRM;
|
||||
|
||||
return 0; /* No result; this is a write cycle */
|
||||
return 0; /* No result; this is a write cycle */
|
||||
}
|
||||
|
||||
|
||||
/* This function expects a Write to Buffer confirmation command
|
||||
(FLASH_CMD_WRITE_BUFFER_2); if it is received, the write buffer
|
||||
is copied into the Flash Rom array, otherwise the write cycle is
|
||||
aborted. In both cases, the new state is FLASH_ST_READ_ARRAY.
|
||||
*/
|
||||
static int WriteConfirm(enum FlashState *state, enum FlashCycle cycle,
|
||||
XAddress address, int data)
|
||||
static int WriteConfirm( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (end)");
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (end)" );
|
||||
|
||||
/* Expect Write to Buffer confirmation code */
|
||||
if(data == FLASH_CMD_WRITE_BUFFER_2)
|
||||
{
|
||||
int i;
|
||||
if ( data == FLASH_CMD_WRITE_BUFFER_2 ) {
|
||||
int i;
|
||||
|
||||
/* Confirmation OK; write.
|
||||
Remember that wb_count is the byte count MINUS 1.
|
||||
*/
|
||||
for(i=0; i<=wb_count; i++)
|
||||
{
|
||||
mod_status_49->flash[NibbleAddress(wb_start+i)]
|
||||
= LowNibble(wb[i]);
|
||||
mod_status_49->flash[NibbleAddress(wb_start+i)+1]
|
||||
= HighNibble(wb[i]);
|
||||
}
|
||||
/* Confirmation OK; write.
|
||||
Remember that wb_count is the byte count MINUS 1.
|
||||
*/
|
||||
for ( i = 0; i <= wb_count; i++ ) {
|
||||
mod_status_49->flash[ NibbleAddress( wb_start + i ) ] = LowNibble( wb[ i ] );
|
||||
mod_status_49->flash[ NibbleAddress( wb_start + i ) + 1 ] = HighNibble( wb[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
*state = FLASH_ST_READ_ARRAY;
|
||||
return 0; /* No result */
|
||||
return 0; /* No result */
|
||||
}
|
||||
|
||||
|
||||
/* If the FLASH_CMD_BL_ERASE_2 command is received, this function erases
|
||||
the block pointed by the current address; otherwise the block erase
|
||||
operation is aborted.
|
||||
In both cases, the new state is FLASH_ST_READ_SR.
|
||||
*/
|
||||
static int BlockErase(enum FlashState *state, enum FlashCycle cycle,
|
||||
XAddress address, int data)
|
||||
static int BlockErase( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Block Erase (end)");
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Block Erase (end)" );
|
||||
|
||||
/* Expect Write to Buffer confirmation code */
|
||||
if(data == FLASH_CMD_BL_ERASE_2)
|
||||
{
|
||||
XAddress block_base = BlockBase(address);
|
||||
int i;
|
||||
if ( data == FLASH_CMD_BL_ERASE_2 ) {
|
||||
XAddress block_base = BlockBase( address );
|
||||
int i;
|
||||
|
||||
/* Confirmation OK; erase */
|
||||
for(i=0; i<BLOCK_SIZE; i++)
|
||||
{
|
||||
mod_status_49->flash[
|
||||
NibbleAddress(block_base+i)] = (Nibble)0xF;
|
||||
mod_status_49->flash[
|
||||
NibbleAddress(block_base+i)+1] = (Nibble)0xF;
|
||||
}
|
||||
/* Confirmation OK; erase */
|
||||
for ( i = 0; i < BLOCK_SIZE; i++ ) {
|
||||
mod_status_49->flash[ NibbleAddress( block_base + i ) ] = ( Nibble )0xF;
|
||||
mod_status_49->flash[ NibbleAddress( block_base + i ) + 1 ] = ( Nibble )0xF;
|
||||
}
|
||||
}
|
||||
|
||||
*state = FLASH_ST_READ_SR;
|
||||
return 0; /* No result */
|
||||
return 0; /* No result */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
FSM state diagram; two-dimensional array of FlashF; each function
|
||||
is invoked when the FSM is in a given state (first index), and
|
||||
a particular cycle (second index) is requested.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
static FlashF F[FLASH_ST_N][FLASH_CYCLE_N] =
|
||||
{
|
||||
{ ReadArray, ParseCommand }, /* FLASH_ST_READ_ARRAY */
|
||||
{ ReadSR, ParseCommand }, /* FLASH_ST_READ_SR */
|
||||
{ ReadXSR, StoreCount }, /* FLASH_ST_READ_XSR */
|
||||
{ BadCommand, StoreData }, /* FLASH_ST_WRITE_DATA_1 */
|
||||
{ BadCommand, StoreData }, /* FLASH_ST_WRITE_DATA_N */
|
||||
{ BadCommand, WriteConfirm }, /* FLASH_ST_WRITE_CONFIRM */
|
||||
{ BadCommand, BlockErase } /* FLASH_ST_BL_ERASE */
|
||||
static FlashF F[ FLASH_ST_N ][ FLASH_CYCLE_N ] = {
|
||||
{ReadArray, ParseCommand}, /* FLASH_ST_READ_ARRAY */
|
||||
{ReadSR, ParseCommand}, /* FLASH_ST_READ_SR */
|
||||
{ReadXSR, StoreCount }, /* FLASH_ST_READ_XSR */
|
||||
{BadCommand, StoreData }, /* FLASH_ST_WRITE_DATA_1 */
|
||||
{BadCommand, StoreData }, /* FLASH_ST_WRITE_DATA_N */
|
||||
{BadCommand, WriteConfirm}, /* FLASH_ST_WRITE_CONFIRM */
|
||||
{BadCommand, BlockErase } /* FLASH_ST_BL_ERASE */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Other private functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
@ -415,25 +362,23 @@ static FlashF F[FLASH_ST_N][FLASH_CYCLE_N] =
|
|||
with 'address' and 'data' as arguments. Returns the
|
||||
result of the FSM, if any.
|
||||
*/
|
||||
static int FSM(enum FlashCycle cycle, XAddress address, int data)
|
||||
static int FSM( enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
int result;
|
||||
|
||||
debug2(DEBUG_C_FLASH, FLASH_I_FSM, fsm_state, cycle);
|
||||
debug2(DEBUG_C_FLASH, FLASH_I_FSM_AD, address, data);
|
||||
debug2( DEBUG_C_FLASH, FLASH_I_FSM, fsm_state, cycle );
|
||||
debug2( DEBUG_C_FLASH, FLASH_I_FSM_AD, address, data );
|
||||
|
||||
result = F[fsm_state][cycle](&fsm_state, cycle, address, data);
|
||||
result = F[ fsm_state ][ cycle ]( &fsm_state, cycle, address, data );
|
||||
|
||||
debug2(DEBUG_C_FLASH, FLASH_I_FSM_RESULT, fsm_state, result);
|
||||
debug2( DEBUG_C_FLASH, FLASH_I_FSM_RESULT, fsm_state, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : FlashRead49
|
||||
|
@ -447,41 +392,38 @@ static int FSM(enum FlashCycle cycle, XAddress address, int data)
|
|||
addresses.
|
||||
|
||||
.call :
|
||||
n = FlashRead49(address);
|
||||
n = FlashRead49(address);
|
||||
.input :
|
||||
XAddress address
|
||||
XAddress address
|
||||
.output :
|
||||
Nibble n
|
||||
Nibble n
|
||||
.status_codes :
|
||||
FLASH_I_READ
|
||||
FLASH_I_FSM_OP
|
||||
FLASH_W_BAD_CMD
|
||||
FLASH_I_READ
|
||||
FLASH_I_FSM_OP
|
||||
FLASH_W_BAD_CMD
|
||||
.notes :
|
||||
3.3, 25-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
Nibble FlashRead49(XAddress address)
|
||||
Nibble FlashRead49( XAddress address )
|
||||
{
|
||||
Nibble result;
|
||||
|
||||
if(IsOdd(address))
|
||||
/* Odd address, return buffered data from previous read */
|
||||
result = HighNibble(r_buffer);
|
||||
if ( IsOdd( address ) )
|
||||
/* Odd address, return buffered data from previous read */
|
||||
result = HighNibble( r_buffer );
|
||||
|
||||
else
|
||||
{
|
||||
/* Even address, invoke FSM */
|
||||
r_buffer = FSM(FLASH_CYCLE_READ, ByteAddress(address), 0);
|
||||
result = LowNibble(r_buffer);
|
||||
else {
|
||||
/* Even address, invoke FSM */
|
||||
r_buffer = FSM( FLASH_CYCLE_READ, ByteAddress( address ), 0 );
|
||||
result = LowNibble( r_buffer );
|
||||
}
|
||||
|
||||
|
||||
debug2(DEBUG_C_TRACE|DEBUG_C_FLASH, FLASH_I_READ, address, result);
|
||||
debug2( DEBUG_C_TRACE | DEBUG_C_FLASH, FLASH_I_READ, address, result );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : FlashWrite49
|
||||
|
@ -494,32 +436,30 @@ Nibble FlashRead49(XAddress address)
|
|||
addresses.
|
||||
|
||||
.call :
|
||||
FlashWrite49(address, datum);
|
||||
FlashWrite49(address, datum);
|
||||
.input :
|
||||
XAddress address
|
||||
Nibble datum
|
||||
XAddress address
|
||||
Nibble datum
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
FLASH_I_WRITE
|
||||
FLASH_I_FSM_OP
|
||||
FLASH_W_BAD_CMD
|
||||
FLASH_W_BAD_ADDRESS
|
||||
FLASH_I_WRITE
|
||||
FLASH_I_FSM_OP
|
||||
FLASH_W_BAD_CMD
|
||||
FLASH_W_BAD_ADDRESS
|
||||
.notes :
|
||||
3.3, 25-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void FlashWrite49(XAddress address, Nibble datum)
|
||||
{
|
||||
debug2(DEBUG_C_TRACE|DEBUG_C_FLASH, FLASH_I_WRITE, address, datum);
|
||||
void FlashWrite49( XAddress address, Nibble datum )
|
||||
{
|
||||
debug2( DEBUG_C_TRACE | DEBUG_C_FLASH, FLASH_I_WRITE, address, datum );
|
||||
|
||||
if(IsOdd(address))
|
||||
/* Odd address, invoke FSM; ignore result */
|
||||
FSM(FLASH_CYCLE_WRITE, ByteAddress(address),
|
||||
w_buffer|ShiftHigh(datum));
|
||||
if ( IsOdd( address ) )
|
||||
/* Odd address, invoke FSM; ignore result */
|
||||
FSM( FLASH_CYCLE_WRITE, ByteAddress( address ), w_buffer | ShiftHigh( datum ) );
|
||||
|
||||
else
|
||||
/* Even address, buffer datum */
|
||||
w_buffer = datum;
|
||||
|
||||
/* Even address, buffer datum */
|
||||
w_buffer = datum;
|
||||
}
|
||||
|
|
117
src/flash49.h
117
src/flash49.h
|
@ -31,7 +31,6 @@
|
|||
|
||||
/* +-+ */
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.identifier : $Id: flash49.h,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
|
@ -72,13 +71,11 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macro/Data type definitions
|
||||
Macro/Data type definitions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define FLASH49_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
|
||||
#define FLASH49_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
|
||||
/* Command Set Definitions, Table 3 on Data Sheet.
|
||||
Both BCS and SCS commands are listed here; commands marked with
|
||||
|
@ -86,79 +83,73 @@
|
|||
|
||||
The last fixed byte of multibyte commands has a '_2' suffix.
|
||||
*/
|
||||
#define FLASH_CMD_READ_ARRAY 0xFF /* BCS */
|
||||
#define FLASH_CMD_READ_ID 0x90 /* BCS (*) */
|
||||
#define FLASH_CMD_READ_QUERY 0x98 /* SCS (*) */
|
||||
#define FLASH_CMD_READ_SR 0x70 /* BCS */
|
||||
#define FLASH_CMD_CLR_SR 0x50 /* BCS */
|
||||
#define FLASH_CMD_WRITE_BUFFER 0xE8 /* SCS */
|
||||
# define FLASH_CMD_WRITE_BUFFER_2 0xD0
|
||||
#define FLASH_CMD_BW_PGM 0x40 /* BCS (*) */
|
||||
#define FLASH_CMD_BW_PGM_ALT 0x10 /* BCS, alternate (*) */
|
||||
#define FLASH_CMD_BL_ERASE 0x20 /* BCS */
|
||||
# define FLASH_CMD_BL_ERASE_2 0xD0
|
||||
#define FLASH_CMD_SUSPEND 0xB0 /* BCS (*) */
|
||||
#define FLASH_CMD_RESUME 0xD0 /* BCS (*) */
|
||||
#define FLASH_CMD_STS_CONFIG 0xB8 /* SCS (*) */
|
||||
#define FLASH_CMD_BL_LB 0x60 /* SCS (*) */
|
||||
# define FLASH_CMD_BL_LB_SET 0x01
|
||||
# define FLASH_CMD_BL_LB_CLR 0xD0
|
||||
#define FLASH_CMD_CHIP_ERASE 0x30 /* SCS (*) */
|
||||
# define FLASH_CMD_CHIP_ERASE_2 0xD0
|
||||
|
||||
#define FLASH_CMD_READ_ARRAY 0xFF /* BCS */
|
||||
#define FLASH_CMD_READ_ID 0x90 /* BCS (*) */
|
||||
#define FLASH_CMD_READ_QUERY 0x98 /* SCS (*) */
|
||||
#define FLASH_CMD_READ_SR 0x70 /* BCS */
|
||||
#define FLASH_CMD_CLR_SR 0x50 /* BCS */
|
||||
#define FLASH_CMD_WRITE_BUFFER 0xE8 /* SCS */
|
||||
#define FLASH_CMD_WRITE_BUFFER_2 0xD0
|
||||
#define FLASH_CMD_BW_PGM 0x40 /* BCS (*) */
|
||||
#define FLASH_CMD_BW_PGM_ALT 0x10 /* BCS, alternate (*) */
|
||||
#define FLASH_CMD_BL_ERASE 0x20 /* BCS */
|
||||
#define FLASH_CMD_BL_ERASE_2 0xD0
|
||||
#define FLASH_CMD_SUSPEND 0xB0 /* BCS (*) */
|
||||
#define FLASH_CMD_RESUME 0xD0 /* BCS (*) */
|
||||
#define FLASH_CMD_STS_CONFIG 0xB8 /* SCS (*) */
|
||||
#define FLASH_CMD_BL_LB 0x60 /* SCS (*) */
|
||||
#define FLASH_CMD_BL_LB_SET 0x01
|
||||
#define FLASH_CMD_BL_LB_CLR 0xD0
|
||||
#define FLASH_CMD_CHIP_ERASE 0x30 /* SCS (*) */
|
||||
#define FLASH_CMD_CHIP_ERASE_2 0xD0
|
||||
|
||||
/* Status Register bit masks, Table 15 on Data Sheet
|
||||
*/
|
||||
#define FLASH_SR_WSMS 0x80 /* WSM state, 0=busy, 1=ready */
|
||||
#define FLASH_SR_ESS 0x40 /* Erase suspend, 1=suspended */
|
||||
#define FLASH_SR_ECLBS 0x20 /* 1=Error during erasure */
|
||||
#define FLASH_SR_BWSLBS 0x10 /* 1=Error during program */
|
||||
#define FLASH_SR_VPPS 0x08 /* 1=Vpp error */
|
||||
#define FLASH_SR_BWSS 0x04 /* Program suspend, 1=suspended */
|
||||
#define FLASH_SR_DPS 0x02 /* 1=Lock encountered */
|
||||
|
||||
|
||||
/* Extended Status Register bit masks, Table 16 on Data Sheet
|
||||
*/
|
||||
#define FLASH_XSR_WBS 0x80 /* Write buffer status 1=available */
|
||||
*/
|
||||
#define FLASH_SR_WSMS 0x80 /* WSM state, 0=busy, 1=ready */
|
||||
#define FLASH_SR_ESS 0x40 /* Erase suspend, 1=suspended */
|
||||
#define FLASH_SR_ECLBS 0x20 /* 1=Error during erasure */
|
||||
#define FLASH_SR_BWSLBS 0x10 /* 1=Error during program */
|
||||
#define FLASH_SR_VPPS 0x08 /* 1=Vpp error */
|
||||
#define FLASH_SR_BWSS 0x04 /* Program suspend, 1=suspended */
|
||||
#define FLASH_SR_DPS 0x02 /* 1=Lock encountered */
|
||||
|
||||
/* Extended Status Register bit masks, Table 16 on Data Sheet
|
||||
*/
|
||||
#define FLASH_XSR_WBS 0x80 /* Write buffer status 1=available */
|
||||
|
||||
/* State of the Flash FSM, derived from command descriptions on
|
||||
pages 16...28 and from flowcharts on Figure 6...12 of Data Sheet
|
||||
*/
|
||||
enum FlashState
|
||||
{
|
||||
FLASH_ST_READ_ARRAY = 0, /* Read Array after CMD_READ_ARRAY */
|
||||
FLASH_ST_READ_SR, /* Read Status Reg. after CMD_READ_SR */
|
||||
FLASH_ST_READ_XSR, /* Read XSR after CMD_WRITE_BUFFER */
|
||||
FLASH_ST_WRITE_DATA_1, /* Write data after ST_WRITE_COUNT */
|
||||
FLASH_ST_WRITE_DATA_N, /* Write data after first write */
|
||||
FLASH_ST_WRITE_CONFIRM, /* Write confirmation after (ST_WRITE_DATA)* */
|
||||
FLASH_ST_BL_ERASE, /* Block erase started */
|
||||
FLASH_ST_N /* Total # of FSM states */
|
||||
enum FlashState {
|
||||
FLASH_ST_READ_ARRAY = 0, /* Read Array after CMD_READ_ARRAY */
|
||||
FLASH_ST_READ_SR, /* Read Status Reg. after CMD_READ_SR */
|
||||
FLASH_ST_READ_XSR, /* Read XSR after CMD_WRITE_BUFFER */
|
||||
FLASH_ST_WRITE_DATA_1, /* Write data after ST_WRITE_COUNT */
|
||||
FLASH_ST_WRITE_DATA_N, /* Write data after first write */
|
||||
FLASH_ST_WRITE_CONFIRM, /* Write confirmation after (ST_WRITE_DATA)* */
|
||||
FLASH_ST_BL_ERASE, /* Block erase started */
|
||||
FLASH_ST_N /* Total # of FSM states */
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf condition codes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define FLASH_I_READ 101 /* Read from address %x: %d */
|
||||
#define FLASH_I_WRITE 102 /* Write address %x, datum %x */
|
||||
#define FLASH_I_FSM 103 /* FSM from state %d, cycle %d */
|
||||
#define FLASH_I_FSM_AD 104 /* FSM address %x, data %x */
|
||||
#define FLASH_I_FSM_RESULT 105 /* FSM next state %d, result %x */
|
||||
#define FLASH_I_FSM_OP 106 /* FSM operation %s */
|
||||
#define FLASH_W_BAD_CMD 201 /* Bad cmd st%d, cycle%d, a%x, d%d */
|
||||
#define FLASH_W_BAD_ADDRESS 202 /* Bad addr st%d, cycle%d, a%x, d%d */
|
||||
#define FLASH_E_xxx 301
|
||||
#define FLASH_F_xxx 401
|
||||
|
||||
#define FLASH_I_READ 101 /* Read from address %x: %d */
|
||||
#define FLASH_I_WRITE 102 /* Write address %x, datum %x */
|
||||
#define FLASH_I_FSM 103 /* FSM from state %d, cycle %d */
|
||||
#define FLASH_I_FSM_AD 104 /* FSM address %x, data %x */
|
||||
#define FLASH_I_FSM_RESULT 105 /* FSM next state %d, result %x */
|
||||
#define FLASH_I_FSM_OP 106 /* FSM operation %s */
|
||||
#define FLASH_W_BAD_CMD 201 /* Bad cmd st%d, cycle%d, a%x, d%d */
|
||||
#define FLASH_W_BAD_ADDRESS 202 /* Bad addr st%d, cycle%d, a%x, d%d */
|
||||
#define FLASH_E_xxx 301
|
||||
#define FLASH_F_xxx 401
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Read/Write operations, nibble-by-nibble */
|
||||
Nibble FlashRead49(XAddress address);
|
||||
void FlashWrite49(XAddress address, Nibble datum);
|
||||
Nibble FlashRead49( XAddress address );
|
||||
void FlashWrite49( XAddress address, Nibble datum );
|
||||
|
|
606
src/hdw.c
606
src/hdw.c
|
@ -106,7 +106,7 @@ static char rcs_id[] = "$Id: hdw.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h> /* 3.1: memset() */
|
||||
#include <string.h> /* 3.1: memset() */
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
|
@ -114,22 +114,18 @@ static char rcs_id[] = "$Id: hdw.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
#include "cpu.h"
|
||||
#include "modules.h"
|
||||
#include "disk_io.h"
|
||||
#include "serial.h" /* 2.5: Serial port emulation module */
|
||||
#include "x_func.h" /* 3.13: Extended emulator functions */
|
||||
#include "serial.h" /* 2.5: Serial port emulation module */
|
||||
#include "x_func.h" /* 3.13: Extended emulator functions */
|
||||
#include "debug.h"
|
||||
|
||||
#include "args.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
static const int addr_mask[] = { 0x0000F, 0x000F0, 0x00F00, 0x0F000, 0xF0000 };
|
||||
|
||||
static const int32 int32_mask[] =
|
||||
{ 0x0000000F, 0x000000F0, 0x00000F00, 0x0000F000,
|
||||
0x000F0000, 0x00F00000, 0x0F000000, 0xF0000000 };
|
||||
|
||||
static const int32 int32_mask[] = { 0x0000000F, 0x000000F0, 0x00000F00, 0x0000F000, 0x000F0000, 0x00F00000, 0x0F000000, 0xF0000000 };
|
||||
|
||||
/* .+
|
||||
|
||||
|
@ -141,35 +137,32 @@ static const int32 int32_mask[] =
|
|||
peripheral devices associated to it from disk.
|
||||
|
||||
.call :
|
||||
HdwInit();
|
||||
HdwInit();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_W_HDW_INIT
|
||||
MOD_I_CALLED
|
||||
MOD_W_HDW_INIT
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, bug fix:
|
||||
memset() invocation was improper, and could lead to memory corruption
|
||||
|
||||
.- */
|
||||
void HdwInit(void)
|
||||
void HdwInit( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "HdwInit");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "HdwInit" );
|
||||
|
||||
if(ReadStructFromFile(args.hdw_file_name, sizeof(mod_status.hdw),
|
||||
&mod_status.hdw))
|
||||
{
|
||||
ChfCondition MOD_W_HDW_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ReadStructFromFile( args.hdw_file_name, sizeof( mod_status.hdw ), &mod_status.hdw ) ) {
|
||||
ChfCondition MOD_W_HDW_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
(void)memset(&mod_status.hdw, 0, sizeof(mod_status.hdw));
|
||||
}
|
||||
( void )memset( &mod_status.hdw, 0, sizeof( mod_status.hdw ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : HdwSave
|
||||
|
@ -180,31 +173,28 @@ void HdwInit(void)
|
|||
to the Hdw module to disk.
|
||||
|
||||
.call :
|
||||
HdwSave();
|
||||
HdwSave();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_HDW_SAVE
|
||||
MOD_I_CALLED
|
||||
MOD_E_HDW_SAVE
|
||||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void HdwSave(void)
|
||||
void HdwSave( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "HdwSave");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "HdwSave" );
|
||||
|
||||
if(WriteStructToFile(&mod_status.hdw, sizeof(mod_status.hdw),
|
||||
args.hdw_file_name))
|
||||
{
|
||||
ChfCondition MOD_E_HDW_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
if ( WriteStructToFile( &mod_status.hdw, sizeof( mod_status.hdw ), args.hdw_file_name ) ) {
|
||||
ChfCondition MOD_E_HDW_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : HdwRead
|
||||
|
@ -214,14 +204,14 @@ void HdwSave(void)
|
|||
This function reads a nibble from the Hdw module.
|
||||
|
||||
.call :
|
||||
d = HdwRead(rel_address);
|
||||
d = HdwRead(rel_address);
|
||||
.input :
|
||||
Address rel_address, relative address
|
||||
Address rel_address, relative address
|
||||
.output :
|
||||
Nibble d, data
|
||||
Nibble d, data
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_W_HDW_READ
|
||||
MOD_I_CALLED
|
||||
MOD_W_HDW_READ
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, update
|
||||
|
@ -232,130 +222,127 @@ void HdwSave(void)
|
|||
- added support for serial port emulation
|
||||
|
||||
.- */
|
||||
Nibble HdwRead(Address rel_address)
|
||||
Nibble HdwRead( Address rel_address )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "HdwRead");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "HdwRead" );
|
||||
|
||||
/* In the following switch, each case corresponds to one hdw register.
|
||||
If the register must be read from the shadow space mod_status.hdw.hdw[],
|
||||
simply put a break in the case, otherwise code any special action for
|
||||
the register and end the case with a return.
|
||||
*/
|
||||
switch(rel_address)
|
||||
{
|
||||
case 0x00: /* LCD driver registers */
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x0B:
|
||||
case 0x0C:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
case 0x28:
|
||||
case 0x29:
|
||||
break;
|
||||
|
||||
case 0x04: /* CRC register */
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
return (Nibble)((mod_status.hdw.crc >> ((rel_address-0x04)*4)) & 0x0F);
|
||||
|
||||
case 0x08: /* Power status */
|
||||
/* No power status related interrupt have occoured */
|
||||
return (Nibble)0;
|
||||
|
||||
case 0x09: /* Power control */
|
||||
break;
|
||||
|
||||
case 0x0D: /* Serial port baud-rate register */
|
||||
break;
|
||||
|
||||
case 0x10: /* Serial port interrupt and I/O control register */
|
||||
return Serial_IOC_Read();
|
||||
|
||||
case 0x11: /* Serial port receiver control/status register */
|
||||
return Serial_RCS_Read();
|
||||
|
||||
case 0x12: /* Serial port transmitter control/status register */
|
||||
return Serial_TCS_Read();
|
||||
|
||||
/* Serial port receiver buffer register; the actual read takes place
|
||||
when the LS nibble is read; serial_rbr buffers the MS nibble.
|
||||
/* In the following switch, each case corresponds to one hdw register.
|
||||
If the register must be read from the shadow space mod_status.hdw.hdw[],
|
||||
simply put a break in the case, otherwise code any special action for
|
||||
the register and end the case with a return.
|
||||
*/
|
||||
case 0x14:
|
||||
return (mod_status.hdw.serial_rbr = Serial_RBR_Read()) & 0x0F;
|
||||
switch ( rel_address ) {
|
||||
case 0x00: /* LCD driver registers */
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x0B:
|
||||
case 0x0C:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
case 0x28:
|
||||
case 0x29:
|
||||
break;
|
||||
|
||||
case 0x15:
|
||||
return (mod_status.hdw.serial_rbr >> 4) & 0x0F;
|
||||
case 0x04: /* CRC register */
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
return ( Nibble )( ( mod_status.hdw.crc >> ( ( rel_address - 0x04 ) * 4 ) ) & 0x0F );
|
||||
|
||||
case 0x0E: /* Card interface */
|
||||
break;
|
||||
case 0x08: /* Power status */
|
||||
/* No power status related interrupt have occoured */
|
||||
return ( Nibble )0;
|
||||
|
||||
case 0x0F: /* Card interface */
|
||||
/* 2.4: Return current card status */
|
||||
return mod_status.hdw.card_status;
|
||||
case 0x09: /* Power control */
|
||||
break;
|
||||
|
||||
case 0x18: /* Service request */
|
||||
case 0x19:
|
||||
break;
|
||||
case 0x0D: /* Serial port baud-rate register */
|
||||
break;
|
||||
|
||||
case 0x1A: /* IR registers */
|
||||
case 0x1C:
|
||||
case 0x1D:
|
||||
break;
|
||||
case 0x10: /* Serial port interrupt and I/O control register */
|
||||
return Serial_IOC_Read();
|
||||
|
||||
case 0x1B: /* Base nibble offset */
|
||||
break;
|
||||
case 0x11: /* Serial port receiver control/status register */
|
||||
return Serial_RCS_Read();
|
||||
|
||||
case 0x1E: /* Scratch pad */
|
||||
break;
|
||||
case 0x12: /* Serial port transmitter control/status register */
|
||||
return Serial_TCS_Read();
|
||||
|
||||
case 0x1F: /* Base Nibble */
|
||||
break;
|
||||
/* Serial port receiver buffer register; the actual read takes place
|
||||
when the LS nibble is read; serial_rbr buffers the MS nibble.
|
||||
*/
|
||||
case 0x14:
|
||||
return ( mod_status.hdw.serial_rbr = Serial_RBR_Read() ) & 0x0F;
|
||||
|
||||
case 0x2E: /* Timer 1 Control */
|
||||
return mod_status.hdw.t1_ctrl;
|
||||
case 0x15:
|
||||
return ( mod_status.hdw.serial_rbr >> 4 ) & 0x0F;
|
||||
|
||||
case 0x2F: /* Timer 2 Control */
|
||||
return mod_status.hdw.t2_ctrl;
|
||||
case 0x0E: /* Card interface */
|
||||
break;
|
||||
|
||||
case 0x0F: /* Card interface */
|
||||
/* 2.4: Return current card status */
|
||||
return mod_status.hdw.card_status;
|
||||
|
||||
case 0x18: /* Service request */
|
||||
case 0x19:
|
||||
break;
|
||||
|
||||
case 0x1A: /* IR registers */
|
||||
case 0x1C:
|
||||
case 0x1D:
|
||||
break;
|
||||
|
||||
case 0x1B: /* Base nibble offset */
|
||||
break;
|
||||
|
||||
case 0x1E: /* Scratch pad */
|
||||
break;
|
||||
|
||||
case 0x1F: /* Base Nibble */
|
||||
break;
|
||||
|
||||
case 0x2E: /* Timer 1 Control */
|
||||
return mod_status.hdw.t1_ctrl;
|
||||
|
||||
case 0x2F: /* Timer 2 Control */
|
||||
return mod_status.hdw.t2_ctrl;
|
||||
|
||||
#ifdef HP49_SUPPORT
|
||||
/* 3.2: The HP49 firmware (1.19-4) reads a nibble from 0x30 */
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x34:
|
||||
return (Nibble)0x0;
|
||||
/* 3.2: The HP49 firmware (1.19-4) reads a nibble from 0x30 */
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x34:
|
||||
return ( Nibble )0x0;
|
||||
#endif
|
||||
|
||||
case 0x37: /* Timer 1 value */
|
||||
return mod_status.hdw.t1_val;
|
||||
case 0x37: /* Timer 1 value */
|
||||
return mod_status.hdw.t1_val;
|
||||
|
||||
case 0x38: /* Timer 2 value */
|
||||
case 0x39:
|
||||
case 0x3A:
|
||||
case 0x3B:
|
||||
case 0x3C:
|
||||
case 0x3D:
|
||||
case 0x3E:
|
||||
case 0x3F:
|
||||
return
|
||||
(Nibble)((mod_status.hdw.t2_val >> ((rel_address-0x38)*4)) & 0x0F);
|
||||
|
||||
default:
|
||||
ChfCondition MOD_W_HDW_READ, CHF_WARNING, rel_address ChfEnd;
|
||||
ChfSignal();
|
||||
return (Nibble)0xF;
|
||||
}
|
||||
case 0x38: /* Timer 2 value */
|
||||
case 0x39:
|
||||
case 0x3A:
|
||||
case 0x3B:
|
||||
case 0x3C:
|
||||
case 0x3D:
|
||||
case 0x3E:
|
||||
case 0x3F:
|
||||
return ( Nibble )( ( mod_status.hdw.t2_val >> ( ( rel_address - 0x38 ) * 4 ) ) & 0x0F );
|
||||
|
||||
/* Read from hdw register array */
|
||||
return mod_status.hdw.hdw[rel_address];
|
||||
default:
|
||||
ChfCondition MOD_W_HDW_READ, CHF_WARNING, rel_address ChfEnd;
|
||||
ChfSignal();
|
||||
return ( Nibble )0xF;
|
||||
}
|
||||
|
||||
/* Read from hdw register array */
|
||||
return mod_status.hdw.hdw[ rel_address ];
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : HdwWrite
|
||||
|
@ -365,201 +352,198 @@ Nibble HdwRead(Address rel_address)
|
|||
This function writes a nibble to the Hdw module.
|
||||
|
||||
.call :
|
||||
HdwWrite(rel_address, data);
|
||||
HdwWrite(rel_address, data);
|
||||
.input :
|
||||
Address rel_address, relative address
|
||||
Nibble data, data to be written
|
||||
Address rel_address, relative address
|
||||
Nibble data, data to be written
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_W_HDW_WRITE
|
||||
MOD_I_CALLED
|
||||
MOD_W_HDW_WRITE
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.5, 14-Sep-2000, update
|
||||
- added support for serial port emulation
|
||||
|
||||
.- */
|
||||
void HdwWrite(Address rel_address, Nibble data)
|
||||
void HdwWrite( Address rel_address, Nibble data )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "HdwWrite");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "HdwWrite" );
|
||||
|
||||
/* This switch has a case for each 'known' hdw register. The code inside the
|
||||
case performs the actions specific for that register; the code following
|
||||
the switch, instead, simply takes care to shadow the hdw register into
|
||||
the mod_status.hdw.hdw[] array
|
||||
*/
|
||||
switch(rel_address)
|
||||
{
|
||||
case 0x00: /* LCD horizontal offset, LCD enable flag */
|
||||
mod_status.hdw.lcd_offset = (int)data & 0x07;
|
||||
mod_status.hdw.lcd_on = ((data & 0x08) != 0);
|
||||
break;
|
||||
|
||||
case 0x01: /* LCD contrast, LS nibble */
|
||||
mod_status.hdw.lcd_contrast &= 0x10;
|
||||
mod_status.hdw.lcd_contrast |= (int)data;
|
||||
break;
|
||||
|
||||
case 0x02: /* LCD contrast, MS bit */
|
||||
mod_status.hdw.lcd_contrast &= 0x0F;
|
||||
mod_status.hdw.lcd_contrast |= (((int)data & 0x01) << 4);
|
||||
break;
|
||||
|
||||
case 0x03: /* LCD test control */
|
||||
break;
|
||||
|
||||
case 0x04: /* CRC register */
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
mod_status.hdw.crc &= ~addr_mask[rel_address-0x04];
|
||||
mod_status.hdw.crc |= ((int)data << ((rel_address-0x04)*4));
|
||||
break;
|
||||
|
||||
case 0x08: /* Power status and power control */
|
||||
case 0x09:
|
||||
break;
|
||||
|
||||
case 0x0B: /* LCD annunciator control (low nibble) */
|
||||
mod_status.hdw.lcd_ann &= 0xF0;
|
||||
mod_status.hdw.lcd_ann |= (int)data;
|
||||
break;
|
||||
|
||||
case 0x0C: /* LCD annunciator control (high nibble) */
|
||||
mod_status.hdw.lcd_ann &= 0x0F;
|
||||
mod_status.hdw.lcd_ann |= ((int)data << 4);
|
||||
break;
|
||||
|
||||
case 0x0D: /* Serial port baud rate */
|
||||
break;
|
||||
|
||||
case 0x0E: /* Card interface */
|
||||
case 0x0F:
|
||||
break;
|
||||
|
||||
case 0x10: /* Serial port interrupt and I/O control/status */
|
||||
Serial_IOC_Write(data);
|
||||
break;
|
||||
|
||||
case 0x11: /* Serial port receiver control/status register */
|
||||
Serial_RCS_Write(data);
|
||||
break;
|
||||
|
||||
case 0x12: /* Serial port transmitter control/status register */
|
||||
Serial_TCS_Write(data);
|
||||
break;
|
||||
|
||||
case 0x13: /* Clear serial port receive error */
|
||||
Serial_CRER_Write(data);
|
||||
break;
|
||||
|
||||
/* 3.13: A write operation into the receiver buffer register
|
||||
triggers an extended emulator function.
|
||||
/* This switch has a case for each 'known' hdw register. The code inside the
|
||||
case performs the actions specific for that register; the code following
|
||||
the switch, instead, simply takes care to shadow the hdw register into
|
||||
the mod_status.hdw.hdw[] array
|
||||
*/
|
||||
case 0x14:
|
||||
ExtendedFunction(data);
|
||||
break;
|
||||
switch ( rel_address ) {
|
||||
case 0x00: /* LCD horizontal offset, LCD enable flag */
|
||||
mod_status.hdw.lcd_offset = ( int )data & 0x07;
|
||||
mod_status.hdw.lcd_on = ( ( data & 0x08 ) != 0 );
|
||||
break;
|
||||
|
||||
/* Serial port transmitter buffer; the actual write takes place
|
||||
when the MS nibble is written; serial_tbr buffers the LS nibble.
|
||||
*/
|
||||
case 0x16:
|
||||
mod_status.hdw.serial_tbr =
|
||||
(mod_status.hdw.serial_tbr & 0xF0) | (int8)data;
|
||||
break;
|
||||
case 0x01: /* LCD contrast, LS nibble */
|
||||
mod_status.hdw.lcd_contrast &= 0x10;
|
||||
mod_status.hdw.lcd_contrast |= ( int )data;
|
||||
break;
|
||||
|
||||
case 0x17:
|
||||
mod_status.hdw.serial_tbr =
|
||||
(mod_status.hdw.serial_tbr & 0x0F) | ((int8)data << 4);
|
||||
Serial_TBR_Write(mod_status.hdw.serial_tbr);
|
||||
break;
|
||||
case 0x02: /* LCD contrast, MS bit */
|
||||
mod_status.hdw.lcd_contrast &= 0x0F;
|
||||
mod_status.hdw.lcd_contrast |= ( ( ( int )data & 0x01 ) << 4 );
|
||||
break;
|
||||
|
||||
case 0x18: /* Service request */
|
||||
case 0x19:
|
||||
break;
|
||||
case 0x03: /* LCD test control */
|
||||
break;
|
||||
|
||||
case 0x1A: /* IR Control Register */
|
||||
break;
|
||||
case 0x04: /* CRC register */
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
mod_status.hdw.crc &= ~addr_mask[ rel_address - 0x04 ];
|
||||
mod_status.hdw.crc |= ( ( int )data << ( ( rel_address - 0x04 ) * 4 ) );
|
||||
break;
|
||||
|
||||
case 0x1B: /* Base nibble offset */
|
||||
break;
|
||||
case 0x08: /* Power status and power control */
|
||||
case 0x09:
|
||||
break;
|
||||
|
||||
case 0x1C: /* IR Status Register */
|
||||
break;
|
||||
case 0x0B: /* LCD annunciator control (low nibble) */
|
||||
mod_status.hdw.lcd_ann &= 0xF0;
|
||||
mod_status.hdw.lcd_ann |= ( int )data;
|
||||
break;
|
||||
|
||||
case 0x1D: /* IR Led Buffer */
|
||||
break;
|
||||
case 0x0C: /* LCD annunciator control (high nibble) */
|
||||
mod_status.hdw.lcd_ann &= 0x0F;
|
||||
mod_status.hdw.lcd_ann |= ( ( int )data << 4 );
|
||||
break;
|
||||
|
||||
case 0x1E: /* Scratch Pad */
|
||||
break;
|
||||
case 0x0D: /* Serial port baud rate */
|
||||
break;
|
||||
|
||||
case 0x1F: /* Base Nibble */
|
||||
break;
|
||||
case 0x0E: /* Card interface */
|
||||
case 0x0F:
|
||||
break;
|
||||
|
||||
case 0x20: /* LCD base address register (write only) */
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
mod_status.hdw.lcd_base_addr &= ~addr_mask[rel_address-0x20];
|
||||
mod_status.hdw.lcd_base_addr |= ((int)data << ((rel_address-0x20)*4));
|
||||
break;
|
||||
case 0x10: /* Serial port interrupt and I/O control/status */
|
||||
Serial_IOC_Write( data );
|
||||
break;
|
||||
|
||||
case 0x25: /* LCD line offset register */
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
mod_status.hdw.lcd_line_offset &= ~addr_mask[rel_address-0x25];
|
||||
mod_status.hdw.lcd_line_offset |= ((int)data << ((rel_address-0x25)*4));
|
||||
break;
|
||||
case 0x11: /* Serial port receiver control/status register */
|
||||
Serial_RCS_Write( data );
|
||||
break;
|
||||
|
||||
case 0x28: /* LCD vertical line count (low nibble) */
|
||||
mod_status.hdw.lcd_vlc &= 0x30;
|
||||
mod_status.hdw.lcd_vlc |= (int)data;
|
||||
break;
|
||||
case 0x12: /* Serial port transmitter control/status register */
|
||||
Serial_TCS_Write( data );
|
||||
break;
|
||||
|
||||
case 0x29: /* LCD vertical line count (higher 2 bits), others (TBD) */
|
||||
mod_status.hdw.lcd_vlc &= 0x0F;
|
||||
mod_status.hdw.lcd_vlc |= (((int)data & 0x03) << 4);
|
||||
case 0x13: /* Clear serial port receive error */
|
||||
Serial_CRER_Write( data );
|
||||
break;
|
||||
|
||||
case 0x2E: /* Timer 1 Control */
|
||||
mod_status.hdw.t1_ctrl = data;
|
||||
break;
|
||||
/* 3.13: A write operation into the receiver buffer register
|
||||
triggers an extended emulator function.
|
||||
*/
|
||||
case 0x14:
|
||||
ExtendedFunction( data );
|
||||
break;
|
||||
|
||||
case 0x2F: /* Timer 2 Control */
|
||||
mod_status.hdw.t2_ctrl = data;
|
||||
break;
|
||||
/* Serial port transmitter buffer; the actual write takes place
|
||||
when the MS nibble is written; serial_tbr buffers the LS nibble.
|
||||
*/
|
||||
case 0x16:
|
||||
mod_status.hdw.serial_tbr = ( mod_status.hdw.serial_tbr & 0xF0 ) | ( int8 )data;
|
||||
break;
|
||||
|
||||
case 0x30: /* LCD menu address register (write only) */
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x34:
|
||||
mod_status.hdw.lcd_menu_addr &= ~addr_mask[rel_address-0x30];
|
||||
mod_status.hdw.lcd_menu_addr |= ((int)data << ((rel_address-0x30)*4));
|
||||
break;
|
||||
case 0x17:
|
||||
mod_status.hdw.serial_tbr = ( mod_status.hdw.serial_tbr & 0x0F ) | ( ( int8 )data << 4 );
|
||||
Serial_TBR_Write( mod_status.hdw.serial_tbr );
|
||||
break;
|
||||
|
||||
case 0x37: /* Timer 1 value */
|
||||
mod_status.hdw.t1_val = data;
|
||||
break;
|
||||
case 0x18: /* Service request */
|
||||
case 0x19:
|
||||
break;
|
||||
|
||||
case 0x38: /* Timer 2 value */
|
||||
case 0x39:
|
||||
case 0x3A:
|
||||
case 0x3B:
|
||||
case 0x3C:
|
||||
case 0x3D:
|
||||
case 0x3E:
|
||||
case 0x3F:
|
||||
mod_status.hdw.t2_val &= ~int32_mask[rel_address-0x38];
|
||||
mod_status.hdw.t2_val |= ((int32)data << ((rel_address-0x38)*4));
|
||||
break;
|
||||
case 0x1A: /* IR Control Register */
|
||||
break;
|
||||
|
||||
default:
|
||||
ChfCondition MOD_W_HDW_WRITE, CHF_WARNING, rel_address, (int)data ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
case 0x1B: /* Base nibble offset */
|
||||
break;
|
||||
|
||||
/* Save copy into hdw register array */
|
||||
mod_status.hdw.hdw[rel_address] = data;
|
||||
case 0x1C: /* IR Status Register */
|
||||
break;
|
||||
|
||||
case 0x1D: /* IR Led Buffer */
|
||||
break;
|
||||
|
||||
case 0x1E: /* Scratch Pad */
|
||||
break;
|
||||
|
||||
case 0x1F: /* Base Nibble */
|
||||
break;
|
||||
|
||||
case 0x20: /* LCD base address register (write only) */
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
mod_status.hdw.lcd_base_addr &= ~addr_mask[ rel_address - 0x20 ];
|
||||
mod_status.hdw.lcd_base_addr |= ( ( int )data << ( ( rel_address - 0x20 ) * 4 ) );
|
||||
break;
|
||||
|
||||
case 0x25: /* LCD line offset register */
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
mod_status.hdw.lcd_line_offset &= ~addr_mask[ rel_address - 0x25 ];
|
||||
mod_status.hdw.lcd_line_offset |= ( ( int )data << ( ( rel_address - 0x25 ) * 4 ) );
|
||||
break;
|
||||
|
||||
case 0x28: /* LCD vertical line count (low nibble) */
|
||||
mod_status.hdw.lcd_vlc &= 0x30;
|
||||
mod_status.hdw.lcd_vlc |= ( int )data;
|
||||
break;
|
||||
|
||||
case 0x29: /* LCD vertical line count (higher 2 bits), others (TBD) */
|
||||
mod_status.hdw.lcd_vlc &= 0x0F;
|
||||
mod_status.hdw.lcd_vlc |= ( ( ( int )data & 0x03 ) << 4 );
|
||||
|
||||
case 0x2E: /* Timer 1 Control */
|
||||
mod_status.hdw.t1_ctrl = data;
|
||||
break;
|
||||
|
||||
case 0x2F: /* Timer 2 Control */
|
||||
mod_status.hdw.t2_ctrl = data;
|
||||
break;
|
||||
|
||||
case 0x30: /* LCD menu address register (write only) */
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x34:
|
||||
mod_status.hdw.lcd_menu_addr &= ~addr_mask[ rel_address - 0x30 ];
|
||||
mod_status.hdw.lcd_menu_addr |= ( ( int )data << ( ( rel_address - 0x30 ) * 4 ) );
|
||||
break;
|
||||
|
||||
case 0x37: /* Timer 1 value */
|
||||
mod_status.hdw.t1_val = data;
|
||||
break;
|
||||
|
||||
case 0x38: /* Timer 2 value */
|
||||
case 0x39:
|
||||
case 0x3A:
|
||||
case 0x3B:
|
||||
case 0x3C:
|
||||
case 0x3D:
|
||||
case 0x3E:
|
||||
case 0x3F:
|
||||
mod_status.hdw.t2_val &= ~int32_mask[ rel_address - 0x38 ];
|
||||
mod_status.hdw.t2_val |= ( ( int32 )data << ( ( rel_address - 0x38 ) * 4 ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
ChfCondition MOD_W_HDW_WRITE, CHF_WARNING, rel_address, ( int )data ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Save copy into hdw register array */
|
||||
mod_status.hdw.hdw[ rel_address ] = data;
|
||||
}
|
||||
|
|
383
src/hw_config.c
383
src/hw_config.c
|
@ -87,194 +87,257 @@ static char rcs_id[] = "$Id: hw_config.c,v 4.1 2000/12/11 09:54:19 cibrario Rel
|
|||
#include "modules.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Module description tables
|
||||
Module description tables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
extern void RomInit(void);
|
||||
extern void HdwInit(void);
|
||||
extern void RamInit(void);
|
||||
extern void Ce1Init(void);
|
||||
extern void Ce2Init(void);
|
||||
extern void NCe3Init(void);
|
||||
extern void RomInit( void );
|
||||
extern void HdwInit( void );
|
||||
extern void RamInit( void );
|
||||
extern void Ce1Init( void );
|
||||
extern void Ce2Init( void );
|
||||
extern void NCe3Init( void );
|
||||
|
||||
extern void RomSave(void);
|
||||
extern void HdwSave(void);
|
||||
extern void RamSave(void);
|
||||
extern void Ce1Save(void);
|
||||
extern void Ce2Save(void);
|
||||
extern void NCe3Save(void);
|
||||
extern void RomSave( void );
|
||||
extern void HdwSave( void );
|
||||
extern void RamSave( void );
|
||||
extern void Ce1Save( void );
|
||||
extern void Ce2Save( void );
|
||||
extern void NCe3Save( void );
|
||||
|
||||
extern Nibble RomRead(Address);
|
||||
extern Nibble HdwRead(Address);
|
||||
extern Nibble RamRead(Address);
|
||||
extern Nibble Ce1Read(Address);
|
||||
extern Nibble Ce2Read(Address);
|
||||
extern Nibble NCe3Read(Address);
|
||||
extern Nibble RomRead( Address );
|
||||
extern Nibble HdwRead( Address );
|
||||
extern Nibble RamRead( Address );
|
||||
extern Nibble Ce1Read( Address );
|
||||
extern Nibble Ce2Read( Address );
|
||||
extern Nibble NCe3Read( Address );
|
||||
|
||||
extern void RomWrite(Address, Nibble);
|
||||
extern void HdwWrite(Address, Nibble);
|
||||
extern void RamWrite(Address, Nibble);
|
||||
extern void Ce1Write(Address, Nibble);
|
||||
extern void Ce2Write(Address, Nibble);
|
||||
extern void NCe3Write(Address, Nibble);
|
||||
extern void RomWrite( Address, Nibble );
|
||||
extern void HdwWrite( Address, Nibble );
|
||||
extern void RamWrite( Address, Nibble );
|
||||
extern void Ce1Write( Address, Nibble );
|
||||
extern void Ce2Write( Address, Nibble );
|
||||
extern void NCe3Write( Address, Nibble );
|
||||
|
||||
extern void RomInit49(void);
|
||||
extern void HdwInit49(void);
|
||||
extern void RamInit49(void);
|
||||
extern void Ce1Init49(void);
|
||||
extern void Ce2Init49(void);
|
||||
extern void NCe3Init49(void);
|
||||
extern void RomInit49( void );
|
||||
extern void HdwInit49( void );
|
||||
extern void RamInit49( void );
|
||||
extern void Ce1Init49( void );
|
||||
extern void Ce2Init49( void );
|
||||
extern void NCe3Init49( void );
|
||||
|
||||
extern void RomSave49(void);
|
||||
extern void HdwSave49(void);
|
||||
extern void RamSave49(void);
|
||||
extern void Ce1Save49(void);
|
||||
extern void Ce2Save49(void);
|
||||
extern void NCe3Save49(void);
|
||||
extern void RomSave49( void );
|
||||
extern void HdwSave49( void );
|
||||
extern void RamSave49( void );
|
||||
extern void Ce1Save49( void );
|
||||
extern void Ce2Save49( void );
|
||||
extern void NCe3Save49( void );
|
||||
|
||||
extern Nibble RomRead49(Address);
|
||||
extern Nibble HdwRead49(Address);
|
||||
extern Nibble RamRead49(Address);
|
||||
extern Nibble Ce1Read49(Address);
|
||||
extern Nibble Ce2Read49(Address);
|
||||
extern Nibble NCe3Read49(Address);
|
||||
extern Nibble RomRead49( Address );
|
||||
extern Nibble HdwRead49( Address );
|
||||
extern Nibble RamRead49( Address );
|
||||
extern Nibble Ce1Read49( Address );
|
||||
extern Nibble Ce2Read49( Address );
|
||||
extern Nibble NCe3Read49( Address );
|
||||
|
||||
extern void RomWrite49(Address, Nibble);
|
||||
extern void HdwWrite49(Address, Nibble);
|
||||
extern void RamWrite49(Address, Nibble);
|
||||
extern void Ce1Write49(Address, Nibble);
|
||||
extern void Ce2Write49(Address, Nibble);
|
||||
extern void NCe3Write49(Address, Nibble);
|
||||
extern void RomWrite49( Address, Nibble );
|
||||
extern void HdwWrite49( Address, Nibble );
|
||||
extern void RamWrite49( Address, Nibble );
|
||||
extern void Ce1Write49( Address, Nibble );
|
||||
extern void Ce2Write49( Address, Nibble );
|
||||
extern void NCe3Write49( Address, Nibble );
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *hw;
|
||||
static const struct {
|
||||
const char* hw;
|
||||
ModDescription description;
|
||||
}
|
||||
|
||||
table[] =
|
||||
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
HP48
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
{
|
||||
"hp48",
|
||||
|
||||
{
|
||||
/* name, id, access_prio,
|
||||
init, save,
|
||||
read, write,
|
||||
r_config, r_abs_base_addr, r_size,
|
||||
map_flags
|
||||
*/
|
||||
/*---------------------------------------------------------------------------
|
||||
HP48
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
{ "ROM (ROM)", 0x00, 0,
|
||||
RomInit, RomSave,
|
||||
RomRead, RomWrite,
|
||||
MOD_CONFIGURED, 0x00000, 0xFFFFF,
|
||||
},
|
||||
{"hp48",
|
||||
|
||||
{ "Hardware Regs. (HDW)", 0x19, 5,
|
||||
HdwInit, HdwSave,
|
||||
HdwRead, HdwWrite,
|
||||
MOD_SIZE_CONFIGURED, 0x00000, 0x00040,
|
||||
},
|
||||
{ /* name, id, access_prio,
|
||||
init, save,
|
||||
read, write,
|
||||
r_config, r_abs_base_addr, r_size,
|
||||
map_flags
|
||||
*/
|
||||
|
||||
{ "Internal RAM (RAM)", 0x03, 4,
|
||||
RamInit, RamSave,
|
||||
RamRead, RamWrite,
|
||||
MOD_UNCONFIGURED, 0, 0,
|
||||
},
|
||||
{
|
||||
"ROM (ROM)",
|
||||
0x00,
|
||||
0,
|
||||
RomInit,
|
||||
RomSave,
|
||||
RomRead,
|
||||
RomWrite,
|
||||
MOD_CONFIGURED,
|
||||
0x00000,
|
||||
0xFFFFF,
|
||||
},
|
||||
|
||||
{ "Bank Select (CE1)", 0x05, 2,
|
||||
Ce1Init, Ce1Save,
|
||||
Ce1Read, Ce1Write,
|
||||
MOD_UNCONFIGURED, 0, 0,
|
||||
},
|
||||
{
|
||||
"Hardware Regs. (HDW)",
|
||||
0x19,
|
||||
5,
|
||||
HdwInit,
|
||||
HdwSave,
|
||||
HdwRead,
|
||||
HdwWrite,
|
||||
MOD_SIZE_CONFIGURED,
|
||||
0x00000,
|
||||
0x00040,
|
||||
},
|
||||
|
||||
{ "Port 1 Control (CE2)", 0x07, 3,
|
||||
Ce2Init, Ce2Save,
|
||||
Ce2Read, Ce2Write,
|
||||
MOD_UNCONFIGURED, 0, 0,
|
||||
},
|
||||
{
|
||||
"Internal RAM (RAM)",
|
||||
0x03,
|
||||
4,
|
||||
RamInit,
|
||||
RamSave,
|
||||
RamRead,
|
||||
RamWrite,
|
||||
MOD_UNCONFIGURED,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
|
||||
{ "Port 2 Control (NCE3)", 0x01, 1,
|
||||
NCe3Init, NCe3Save,
|
||||
NCe3Read, NCe3Write,
|
||||
MOD_UNCONFIGURED, 0, 0,
|
||||
}
|
||||
}},
|
||||
{
|
||||
"Bank Select (CE1)",
|
||||
0x05,
|
||||
2,
|
||||
Ce1Init,
|
||||
Ce1Save,
|
||||
Ce1Read,
|
||||
Ce1Write,
|
||||
MOD_UNCONFIGURED,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
HP49
|
||||
---------------------------------------------------------------------------*/
|
||||
{
|
||||
"Port 1 Control (CE2)",
|
||||
0x07,
|
||||
3,
|
||||
Ce2Init,
|
||||
Ce2Save,
|
||||
Ce2Read,
|
||||
Ce2Write,
|
||||
MOD_UNCONFIGURED,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
|
||||
{
|
||||
"hp49",
|
||||
{
|
||||
"Port 2 Control (NCE3)",
|
||||
0x01,
|
||||
1,
|
||||
NCe3Init,
|
||||
NCe3Save,
|
||||
NCe3Read,
|
||||
NCe3Write,
|
||||
MOD_UNCONFIGURED,
|
||||
0,
|
||||
0,
|
||||
} } },
|
||||
|
||||
{
|
||||
/* name, id, access_prio,
|
||||
init, save,
|
||||
read, write,
|
||||
r_config, r_abs_base_addr, r_size,
|
||||
map_flags
|
||||
*/
|
||||
/*---------------------------------------------------------------------------
|
||||
HP49
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
{ "ROM (ROM)", 0x00, 0,
|
||||
RomInit49, RomSave49,
|
||||
RomRead49, RomWrite49,
|
||||
MOD_CONFIGURED, 0x00000, 0xFFFFF,
|
||||
},
|
||||
{"hp49",
|
||||
|
||||
{ "Hardware Regs. (HDW)", 0x19, 5,
|
||||
HdwInit, HdwSave,
|
||||
HdwRead, HdwWrite,
|
||||
MOD_SIZE_CONFIGURED, 0x00000, 0x00040,
|
||||
},
|
||||
{ /* name, id, access_prio,
|
||||
init, save,
|
||||
read, write,
|
||||
r_config, r_abs_base_addr, r_size,
|
||||
map_flags
|
||||
*/
|
||||
|
||||
{ "IRAM (RAM)", 0x03, 4,
|
||||
RamInit49, RamSave49,
|
||||
RamRead49, RamWrite49,
|
||||
MOD_UNCONFIGURED, 0, 0,
|
||||
},
|
||||
{
|
||||
"ROM (ROM)",
|
||||
0x00,
|
||||
0,
|
||||
RomInit49,
|
||||
RomSave49,
|
||||
RomRead49,
|
||||
RomWrite49,
|
||||
MOD_CONFIGURED,
|
||||
0x00000,
|
||||
0xFFFFF,
|
||||
},
|
||||
|
||||
{ "Bank Select (CE1)", 0x05, 2,
|
||||
Ce1Init49, Ce1Save49,
|
||||
Ce1Read49, Ce1Write49,
|
||||
MOD_UNCONFIGURED, 0, 0,
|
||||
},
|
||||
{
|
||||
"Hardware Regs. (HDW)",
|
||||
0x19,
|
||||
5,
|
||||
HdwInit,
|
||||
HdwSave,
|
||||
HdwRead,
|
||||
HdwWrite,
|
||||
MOD_SIZE_CONFIGURED,
|
||||
0x00000,
|
||||
0x00040,
|
||||
},
|
||||
|
||||
{ "ERAM Bank 0 (CE2)", 0x07, 3,
|
||||
Ce2Init49, Ce2Save49,
|
||||
Ce2Read49, Ce2Write49,
|
||||
MOD_UNCONFIGURED, 0, 0,
|
||||
},
|
||||
{
|
||||
"IRAM (RAM)",
|
||||
0x03,
|
||||
4,
|
||||
RamInit49,
|
||||
RamSave49,
|
||||
RamRead49,
|
||||
RamWrite49,
|
||||
MOD_UNCONFIGURED,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
|
||||
{ "ERAM Bank 1 (NCE3)", 0x01, 1,
|
||||
NCe3Init49, NCe3Save49,
|
||||
NCe3Read49, NCe3Write49,
|
||||
MOD_UNCONFIGURED, 0, 0,
|
||||
MOD_MAP_FLAGS_ABS
|
||||
}
|
||||
}}
|
||||
{
|
||||
"Bank Select (CE1)",
|
||||
0x05,
|
||||
2,
|
||||
Ce1Init49,
|
||||
Ce1Save49,
|
||||
Ce1Read49,
|
||||
Ce1Write49,
|
||||
MOD_UNCONFIGURED,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
|
||||
{
|
||||
"ERAM Bank 0 (CE2)",
|
||||
0x07,
|
||||
3,
|
||||
Ce2Init49,
|
||||
Ce2Save49,
|
||||
Ce2Read49,
|
||||
Ce2Write49,
|
||||
MOD_UNCONFIGURED,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
|
||||
{ "ERAM Bank 1 (NCE3)", 0x01, 1, NCe3Init49, NCe3Save49, NCe3Read49, NCe3Write49, MOD_UNCONFIGURED, 0, 0,
|
||||
MOD_MAP_FLAGS_ABS } }}
|
||||
};
|
||||
|
||||
#define N_DESCRIPTIONS (sizeof(table)/sizeof(table[0]))
|
||||
|
||||
#define N_DESCRIPTIONS ( sizeof( table ) / sizeof( table[ 0 ] ) )
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ModSelectDescription
|
||||
|
@ -286,32 +349,32 @@ table[] =
|
|||
string passed as argument.
|
||||
|
||||
.call :
|
||||
ModSelectDescription(hw)
|
||||
ModSelectDescription(hw)
|
||||
.input :
|
||||
const char *hw, hardware configuration string
|
||||
const char *hw, hardware configuration string
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_NO_MATCH
|
||||
MOD_I_CALLED
|
||||
MOD_E_NO_MATCH
|
||||
.notes :
|
||||
1.1, 28-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
void ModSelectDescription(const char *hw)
|
||||
void ModSelectDescription( const char* hw )
|
||||
{
|
||||
int i;
|
||||
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "ModSelectDescription");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ModSelectDescription" );
|
||||
|
||||
for(i=0; i<N_DESCRIPTIONS && strcmp(hw, table[i].hw); i++);
|
||||
for ( i = 0; i < N_DESCRIPTIONS && strcmp( hw, table[ i ].hw ); i++ )
|
||||
;
|
||||
|
||||
if(i==N_DESCRIPTIONS)
|
||||
{
|
||||
ChfCondition MOD_E_NO_MATCH, CHF_ERROR, hw ChfEnd;
|
||||
ChfSignal();
|
||||
if ( i == N_DESCRIPTIONS ) {
|
||||
ChfCondition MOD_E_NO_MATCH, CHF_ERROR, hw ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else
|
||||
ModRegisterDescription(table[i].description);
|
||||
ModRegisterDescription( table[ i ].description );
|
||||
}
|
||||
|
|
196
src/keyb.c
196
src/keyb.c
|
@ -51,7 +51,7 @@
|
|||
x48 source code by Eddie C. Dost (ecd@dressler.de)
|
||||
|
||||
NOTE: In the current (r1.1) implementation,
|
||||
the emulation accuracy could be poor.
|
||||
the emulation accuracy could be poor.
|
||||
|
||||
.include : config.h, machdep.h, cpu.h, modules.h, keyb.h
|
||||
|
||||
|
@ -97,18 +97,17 @@ static char rcs_id[] = "$Id: keyb.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
#include "keyb.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
#define OUT_BITS 12
|
||||
#define OUT_BITS 12
|
||||
|
||||
/* cur_in:
|
||||
|
||||
This array contains the current value the CPU IN register will assume
|
||||
for each bit set in the OUT register.
|
||||
*/
|
||||
static InputRegister cur_in[OUT_BITS];
|
||||
|
||||
static InputRegister cur_in[ OUT_BITS ];
|
||||
|
||||
/* .+
|
||||
|
||||
|
@ -121,29 +120,27 @@ static InputRegister cur_in[OUT_BITS];
|
|||
interrupt request if any key is pressed.
|
||||
|
||||
NOTE: This function currently (r1.1) always posts an IRQ request; perhaps,
|
||||
if the ON key is down, a NMI request should be posted instead.
|
||||
if the ON key is down, a NMI request should be posted instead.
|
||||
|
||||
.call :
|
||||
KeybRSI();
|
||||
KeybRSI();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
*
|
||||
*
|
||||
.notes :
|
||||
1.1, 17-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void KeybRSI(void)
|
||||
void KeybRSI( void )
|
||||
{
|
||||
/* Post an IRQ if the IN register is not zero */
|
||||
/* Post an IRQ if the IN register is not zero */
|
||||
|
||||
CpuIntRequest(KeybIN((OutputRegister)0x1FF) != (InputRegister)0 ?
|
||||
INT_REQUEST_IRQ : INT_REQUEST_NONE);
|
||||
CpuIntRequest( KeybIN( ( OutputRegister )0x1FF ) != ( InputRegister )0 ? INT_REQUEST_IRQ : INT_REQUEST_NONE );
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : KeybIn
|
||||
|
@ -155,36 +152,35 @@ void KeybRSI(void)
|
|||
value of the IN register for the given value of the OUT reguster.
|
||||
|
||||
.call :
|
||||
in = KeybIN(out);
|
||||
in = KeybIN(out);
|
||||
.input :
|
||||
OutputRegister out, current value of the OUT register
|
||||
OutputRegister out, current value of the OUT register
|
||||
.output :
|
||||
InputRegister in, computed value of the IN register
|
||||
InputRegister in, computed value of the IN register
|
||||
.status_codes :
|
||||
*
|
||||
*
|
||||
.notes :
|
||||
1.1, 17-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
InputRegister KeybIN(OutputRegister out)
|
||||
InputRegister KeybIN( OutputRegister out )
|
||||
{
|
||||
/* Compute the current value of the IN register */
|
||||
InputRegister in = (InputRegister)0;
|
||||
int bit;
|
||||
/* Compute the current value of the IN register */
|
||||
InputRegister in = ( InputRegister )0;
|
||||
int bit;
|
||||
|
||||
/* For each bit set in the 'out' register, OR the corresponding IN register
|
||||
value into 'in'
|
||||
*/
|
||||
for(bit=0; bit<OUT_BITS; bit++)
|
||||
{
|
||||
if(out & 0x01) in |= cur_in[bit];
|
||||
out >>= 1;
|
||||
}
|
||||
/* For each bit set in the 'out' register, OR the corresponding IN register
|
||||
value into 'in'
|
||||
*/
|
||||
for ( bit = 0; bit < OUT_BITS; bit++ ) {
|
||||
if ( out & 0x01 )
|
||||
in |= cur_in[ bit ];
|
||||
out >>= 1;
|
||||
}
|
||||
|
||||
return in;
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : KeybPress
|
||||
|
@ -196,63 +192,57 @@ InputRegister KeybIN(OutputRegister out)
|
|||
necessary, posts an interrupt request to the CPU.
|
||||
|
||||
.call :
|
||||
KeybPress(key);
|
||||
KeybPress(key);
|
||||
.input :
|
||||
const char *key, identifies the key that has been pressed.
|
||||
const char *key, identifies the key that has been pressed.
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_W_BAD_KEY
|
||||
MOD_W_BAD_OUT_BIT
|
||||
MOD_W_BAD_KEY
|
||||
MOD_W_BAD_OUT_BIT
|
||||
.notes :
|
||||
1.1, 17-Feb-1998, creation
|
||||
2.1, 6-Sep-2000,
|
||||
deeply revised to accomodate the new GUI
|
||||
|
||||
.- */
|
||||
void KeybPress(const char *key)
|
||||
void KeybPress( const char* key )
|
||||
{
|
||||
if(strcmp(key, "*") == 0)
|
||||
{
|
||||
/* This is the ON key */
|
||||
int i;
|
||||
if ( strcmp( key, "*" ) == 0 ) {
|
||||
/* This is the ON key */
|
||||
int i;
|
||||
|
||||
/* Set all 0x8000 lines */
|
||||
for(i=0; i<OUT_BITS; i++) cur_in[i] |= 0x8000;
|
||||
/* Set all 0x8000 lines */
|
||||
for ( i = 0; i < OUT_BITS; i++ )
|
||||
cur_in[ i ] |= 0x8000;
|
||||
|
||||
/* Post an interrupt request to the CPU */
|
||||
CpuIntRequest(INT_REQUEST_NMI);
|
||||
/* Post an interrupt request to the CPU */
|
||||
CpuIntRequest( INT_REQUEST_NMI );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
int in_val, out_bit;
|
||||
else {
|
||||
int in_val, out_bit;
|
||||
|
||||
if(sscanf(key, "%x/%x", &out_bit, &in_val) != 2)
|
||||
{
|
||||
ChfCondition MOD_W_BAD_KEY, CHF_WARNING, key ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
if ( sscanf( key, "%x/%x", &out_bit, &in_val ) != 2 ) {
|
||||
ChfCondition MOD_W_BAD_KEY, CHF_WARNING, key ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else if(out_bit < 0 || out_bit >= OUT_BITS)
|
||||
{
|
||||
ChfCondition MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
else if ( out_bit < 0 || out_bit >= OUT_BITS ) {
|
||||
ChfCondition MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Update the cur_in array */
|
||||
cur_in[out_bit] |= in_val;
|
||||
else {
|
||||
/* Update the cur_in array */
|
||||
cur_in[ out_bit ] |= in_val;
|
||||
|
||||
/* Post an interrupt request to the CPU */
|
||||
CpuIntRequest(INT_REQUEST_NMI);
|
||||
|
||||
}
|
||||
/* Post an interrupt request to the CPU */
|
||||
CpuIntRequest( INT_REQUEST_NMI );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : KeybRelease
|
||||
|
@ -263,56 +253,51 @@ void KeybPress(const char *key)
|
|||
released. It updates the internal keyboard status information.
|
||||
|
||||
.call :
|
||||
KeybRelease(key);
|
||||
KeybRelease(key);
|
||||
.input :
|
||||
const char *key, identifies the key that has been released.
|
||||
const char *key, identifies the key that has been released.
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_W_BAD_KEY
|
||||
MOD_W_BAD_OUT_BIT
|
||||
MOD_W_BAD_KEY
|
||||
MOD_W_BAD_OUT_BIT
|
||||
.notes :
|
||||
1.1, 17-Feb-1998, creation
|
||||
2.1, 6-Sep-2000,
|
||||
deeply revised to accomodate the new GUI
|
||||
|
||||
.- */
|
||||
void KeybRelease(const char *key)
|
||||
void KeybRelease( const char* key )
|
||||
{
|
||||
if(strcmp(key, "*") == 0)
|
||||
{
|
||||
/* This is the ON key */
|
||||
int i;
|
||||
if ( strcmp( key, "*" ) == 0 ) {
|
||||
/* This is the ON key */
|
||||
int i;
|
||||
|
||||
/* Reset all 0x8000 lines */
|
||||
for(i=0; i<OUT_BITS; i++) cur_in[i] &= 0x7FFF;
|
||||
/* Reset all 0x8000 lines */
|
||||
for ( i = 0; i < OUT_BITS; i++ )
|
||||
cur_in[ i ] &= 0x7FFF;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
int in_val, out_bit;
|
||||
else {
|
||||
int in_val, out_bit;
|
||||
|
||||
if(sscanf(key, "%x/%x", &out_bit, &in_val) != 2)
|
||||
{
|
||||
ChfCondition MOD_W_BAD_KEY, CHF_WARNING, key ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
if ( sscanf( key, "%x/%x", &out_bit, &in_val ) != 2 ) {
|
||||
ChfCondition MOD_W_BAD_KEY, CHF_WARNING, key ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else if(out_bit < 0 || out_bit >= OUT_BITS)
|
||||
{
|
||||
ChfCondition MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
else if ( out_bit < 0 || out_bit >= OUT_BITS ) {
|
||||
ChfCondition MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Update the cur_in array */
|
||||
cur_in[out_bit] &= ~in_val;
|
||||
}
|
||||
else {
|
||||
/* Update the cur_in array */
|
||||
cur_in[ out_bit ] &= ~in_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : KeybReset
|
||||
|
@ -322,20 +307,21 @@ void KeybRelease(const char *key)
|
|||
This function resets the emulated keyboard; all keys are released.
|
||||
|
||||
.call :
|
||||
KeybReset();
|
||||
KeybReset();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
.notes :
|
||||
3.13, 7-Nov-2000, creation
|
||||
|
||||
.- */
|
||||
void KeybReset(void)
|
||||
void KeybReset( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Reset all 0x8000 lines */
|
||||
for(i=0; i<OUT_BITS; i++) cur_in[i] = 0;
|
||||
for ( i = 0; i < OUT_BITS; i++ )
|
||||
cur_in[ i ] = 0;
|
||||
}
|
||||
|
|
13
src/keyb.h
13
src/keyb.h
|
@ -76,13 +76,12 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
void KeybRSI(void);
|
||||
InputRegister KeybIN(OutputRegister out);
|
||||
void KeybPress(const char *key);
|
||||
void KeybRelease(const char *key);
|
||||
void KeybReset(void);
|
||||
void KeybRSI( void );
|
||||
InputRegister KeybIN( OutputRegister out );
|
||||
void KeybPress( const char* key );
|
||||
void KeybRelease( const char* key );
|
||||
void KeybReset( void );
|
||||
|
|
384
src/libChf/Chf.h
384
src/libChf/Chf.h
|
@ -51,321 +51,263 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Win32 & UNICODE support
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef _WIN32
|
||||
#define ChfChar TCHAR
|
||||
#define ChfText(x) _T(x)
|
||||
#define ChfSigjmp_buf jmp_buf
|
||||
#define ChfSigsetjmp(x,y) setjmp(x)
|
||||
#define ChfSiglongjmp(x,y) longjmp(x,y)
|
||||
# define ChfChar TCHAR
|
||||
# define ChfText( x ) _T( x )
|
||||
# define ChfSigjmp_buf jmp_buf
|
||||
# define ChfSigsetjmp( x, y ) setjmp( x )
|
||||
# define ChfSiglongjmp( x, y ) longjmp( x, y )
|
||||
#else
|
||||
#define ChfChar char
|
||||
#define ChfText(x) x
|
||||
#define ChfSigjmp_buf sigjmp_buf
|
||||
#define ChfSigsetjmp(x,y) sigsetjmp(x,y)
|
||||
#define ChfSiglongjmp(x,y) siglongjmp(x,y)
|
||||
# define ChfChar char
|
||||
# define ChfText( x ) x
|
||||
# define ChfSigjmp_buf sigjmp_buf
|
||||
# define ChfSigsetjmp( x, y ) sigsetjmp( x, y )
|
||||
# define ChfSiglongjmp( x, y ) siglongjmp( x, y )
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
CHF implementation limits and other symbolic constants
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define CHF_MAX_MESSAGE_LENGTH 256
|
||||
#define CHF_UNKNOWN_LINE_NUMBER (-1)
|
||||
#define CHF_UNKNOWN_FILE_NAME (ChfChar *)NULL
|
||||
#define CHF_NULL_DESCRIPTOR (ChfDescriptor *)NULL
|
||||
#define CHF_NULL_CONTEXT (void *)NULL
|
||||
#define CHF_NULL_POINTER (ChfPointer *)NULL
|
||||
#define CHF_NULL_HANDLER (ChfHandler)NULL
|
||||
#define CHF_LIBRARY_ID ChfText("$Id: Chf.h,v 2.2 2001/01/25 11:56:44 cibrario Exp $")
|
||||
#define CHF_MAX_MESSAGE_LENGTH 256
|
||||
#define CHF_UNKNOWN_LINE_NUMBER ( -1 )
|
||||
#define CHF_UNKNOWN_FILE_NAME ( ChfChar* )NULL
|
||||
#define CHF_NULL_DESCRIPTOR ( ChfDescriptor* )NULL
|
||||
#define CHF_NULL_CONTEXT ( void* )NULL
|
||||
#define CHF_NULL_POINTER ( ChfPointer* )NULL
|
||||
#define CHF_NULL_HANDLER ( ChfHandler ) NULL
|
||||
#define CHF_LIBRARY_ID ChfText( "$Id: Chf.h,v 2.2 2001/01/25 11:56:44 cibrario Exp $" )
|
||||
|
||||
#define CHF_MAJOR_RELEASE_NUMBER 2
|
||||
#define CHF_MINOR_RELEASE_NUMBER 2
|
||||
|
||||
#define CHF_MODULE_NAMES_SET 1
|
||||
#define CHF_SET 2
|
||||
#define CHF_ERRNO_SET 3
|
||||
#define CHF_MAJOR_RELEASE_NUMBER 2
|
||||
#define CHF_MINOR_RELEASE_NUMBER 2
|
||||
|
||||
#define CHF_MODULE_NAMES_SET 1
|
||||
#define CHF_SET 2
|
||||
#define CHF_ERRNO_SET 3
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Condition codes
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define CHF_S_OK 0
|
||||
#define CHF_F_COND_STACK_FULL 1 /* Condition stack is full */
|
||||
#define CHF_F_HDLR_STACK_FULL 2 /* Handler stack is full */
|
||||
#define CHF_F_HDLR_STACK_EMPTY 3 /* Handler stack is empty */
|
||||
#define CHF_F_BAD_STATE 4 /* Bad CHF state for req. operation */
|
||||
#define CHF_F_INVALID_ACTION 5 /* Invalid action from handler: %d */
|
||||
#define CHF_F_MALLOC 6 /* Dynamic memory allocation failed */
|
||||
#define CHF_F_NOT_AVAILABLE 7 /* Function not available */
|
||||
#define CHF_F_SETLOCALE 10 /* setlocale() failed */
|
||||
#define CHF_F_CATOPEN 11 /* catopen() failed */
|
||||
|
||||
#define CHF_S_OK 0
|
||||
#define CHF_F_COND_STACK_FULL 1 /* Condition stack is full */
|
||||
#define CHF_F_HDLR_STACK_FULL 2 /* Handler stack is full */
|
||||
#define CHF_F_HDLR_STACK_EMPTY 3 /* Handler stack is empty */
|
||||
#define CHF_F_BAD_STATE 4 /* Bad CHF state for req. operation */
|
||||
#define CHF_F_INVALID_ACTION 5 /* Invalid action from handler: %d */
|
||||
#define CHF_F_MALLOC 6 /* Dynamic memory allocation failed */
|
||||
#define CHF_F_NOT_AVAILABLE 7 /* Function not available */
|
||||
#define CHF_F_SETLOCALE 10 /* setlocale() failed */
|
||||
#define CHF_F_CATOPEN 11 /* catopen() failed */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Type definitions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
typedef enum /* Condition severity codes */
|
||||
{
|
||||
CHF_SUCCESS,
|
||||
CHF_INFO,
|
||||
typedef enum /* Condition severity codes */
|
||||
{ CHF_SUCCESS,
|
||||
CHF_INFO,
|
||||
CHF_WARNING,
|
||||
CHF_ERROR,
|
||||
CHF_FATAL
|
||||
}
|
||||
ChfSeverity;
|
||||
CHF_FATAL } ChfSeverity;
|
||||
|
||||
typedef enum /* Condition handler action codes */
|
||||
{
|
||||
CHF_CONTINUE, /* Continue application */
|
||||
CHF_RESIGNAL, /* Resignal to next handler */
|
||||
CHF_UNWIND, /* Stack unwind */
|
||||
CHF_UNWIND_KEEP /* Unwind, keep last cond. group */
|
||||
}
|
||||
ChfAction;
|
||||
typedef enum /* Condition handler action codes */
|
||||
{ CHF_CONTINUE, /* Continue application */
|
||||
CHF_RESIGNAL, /* Resignal to next handler */
|
||||
CHF_UNWIND, /* Stack unwind */
|
||||
CHF_UNWIND_KEEP /* Unwind, keep last cond. group */
|
||||
} ChfAction;
|
||||
|
||||
typedef int /* CHF options */
|
||||
ChfOptions;
|
||||
typedef int /* CHF options */
|
||||
ChfOptions;
|
||||
|
||||
#define CHF_DEFAULT 0x0000 /* default flags */
|
||||
#define CHF_ABORT 0x0001 /* use abort() instead of exit() */
|
||||
#define CHF_DEFAULT 0x0000 /* default flags */
|
||||
#define CHF_ABORT 0x0001 /* use abort() instead of exit() */
|
||||
|
||||
typedef enum /* Current CHF state */
|
||||
{
|
||||
CHF_UNKNOWN,
|
||||
typedef enum /* Current CHF state */
|
||||
{ CHF_UNKNOWN,
|
||||
CHF_IDLE,
|
||||
CHF_SIGNALING,
|
||||
CHF_UNWINDING,
|
||||
CHF_SIGNAL_UNWINDING
|
||||
}
|
||||
ChfState;
|
||||
CHF_SIGNAL_UNWINDING } ChfState;
|
||||
|
||||
typedef struct ChfDescriptor_S /* Condition descriptor */
|
||||
typedef struct ChfDescriptor_S /* Condition descriptor */
|
||||
{
|
||||
int module_id; /* Module identifier */
|
||||
int condition_code; /* Condition code */
|
||||
ChfSeverity severity; /* Severity */
|
||||
int line_number; /* Line # or CHF_UNK_LINE_NUMBER */
|
||||
const ChfChar *file_name; /* File name or CHF_UNK_FILE_NAME */
|
||||
ChfChar message[CHF_MAX_MESSAGE_LENGTH]; /* Partial message */
|
||||
struct ChfDescriptor_S *next; /* Link to next descriptor */
|
||||
}
|
||||
ChfDescriptor;
|
||||
int module_id; /* Module identifier */
|
||||
int condition_code; /* Condition code */
|
||||
ChfSeverity severity; /* Severity */
|
||||
int line_number; /* Line # or CHF_UNK_LINE_NUMBER */
|
||||
const ChfChar* file_name; /* File name or CHF_UNK_FILE_NAME */
|
||||
ChfChar message[ CHF_MAX_MESSAGE_LENGTH ]; /* Partial message */
|
||||
struct ChfDescriptor_S* next; /* Link to next descriptor */
|
||||
} ChfDescriptor;
|
||||
|
||||
typedef struct ChfTable_S /* Standalone message table */
|
||||
typedef struct ChfTable_S /* Standalone message table */
|
||||
{
|
||||
int module; /* Module identifier */
|
||||
int code; /* Condition code */
|
||||
ChfChar *msg_template; /* Message template */
|
||||
}
|
||||
ChfTable;
|
||||
int module; /* Module identifier */
|
||||
int code; /* Condition code */
|
||||
ChfChar* msg_template; /* Message template */
|
||||
} ChfTable;
|
||||
|
||||
typedef /* Generic pointer */
|
||||
void *ChfPointer;
|
||||
typedef /* Generic pointer */
|
||||
void* ChfPointer;
|
||||
|
||||
typedef /* Condition handler */
|
||||
ChfAction (*ChfHandler)(
|
||||
const ChfDescriptor *,
|
||||
const ChfState,
|
||||
ChfPointer
|
||||
);
|
||||
typedef /* Condition handler */
|
||||
ChfAction ( *ChfHandler )( const ChfDescriptor*, const ChfState, ChfPointer );
|
||||
|
||||
typedef /* Message retrieval 'get_message' function */
|
||||
const ChfChar * (*ChfMrsGet)(
|
||||
void *,
|
||||
const int,
|
||||
const int,
|
||||
const ChfChar *default_message
|
||||
);
|
||||
|
||||
typedef /* Message retrieval 'exit' function */
|
||||
void (*ChfMrsExit)(
|
||||
void *
|
||||
);
|
||||
typedef /* Message retrieval 'get_message' function */
|
||||
const ChfChar* ( *ChfMrsGet )( void*, const int, const int, const ChfChar* default_message );
|
||||
|
||||
typedef /* Message retrieval 'exit' function */
|
||||
void ( *ChfMrsExit )( void* );
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Condition generation macros
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CHF_EXTENDED_INFO)
|
||||
#define ChfCondition \
|
||||
#if defined( CHF_EXTENDED_INFO )
|
||||
# define ChfCondition \
|
||||
ChfGenerate( \
|
||||
CHF_MODULE_ID, \
|
||||
ChfText(__FILE__), __LINE__,
|
||||
|
||||
#ifdef _WIN32
|
||||
#define ChfErrnoCondition
|
||||
#else
|
||||
#define ChfErrnoCondition \
|
||||
ChfGenerate( \
|
||||
CHF_ERRNO_SET, \
|
||||
ChfText(__FILE__), __LINE__, \
|
||||
errno, \
|
||||
CHF_ERROR \
|
||||
)
|
||||
#endif
|
||||
# ifdef _WIN32
|
||||
# define ChfErrnoCondition
|
||||
# else
|
||||
# define ChfErrnoCondition ChfGenerate( CHF_ERRNO_SET, ChfText( __FILE__ ), __LINE__, errno, CHF_ERROR )
|
||||
# endif
|
||||
|
||||
#else
|
||||
#define ChfCondition \
|
||||
# define ChfCondition \
|
||||
ChfGenerate( \
|
||||
CHF_MODULE_ID, \
|
||||
CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER,
|
||||
|
||||
#ifdef _WIN32
|
||||
#define ChfErrnoCondition
|
||||
#else
|
||||
#define ChfErrnoCondition \
|
||||
ChfGenerate( \
|
||||
CHF_ERRNO_SET, \
|
||||
CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER, \
|
||||
errno, \
|
||||
CHF_ERROR \
|
||||
)
|
||||
#endif
|
||||
# ifdef _WIN32
|
||||
# define ChfErrnoCondition
|
||||
# else
|
||||
# define ChfErrnoCondition ChfGenerate( CHF_ERRNO_SET, CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER, errno, CHF_ERROR )
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#define ChfEnd \
|
||||
#define ChfEnd \
|
||||
)
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Structured condition handling
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define ChfTry \
|
||||
{\
|
||||
ChfSigjmp_buf _chf_sigjmp_buf;\
|
||||
if(ChfSigsetjmp(_chf_sigjmp_buf, 1) == 0)\
|
||||
{\
|
||||
ChfPushHandler(CHF_NULL_HANDLER, _chf_sigjmp_buf, CHF_NULL_POINTER);
|
||||
#define ChfTry \
|
||||
{ \
|
||||
ChfSigjmp_buf _chf_sigjmp_buf; \
|
||||
if ( ChfSigsetjmp( _chf_sigjmp_buf, 1 ) == 0 ) { \
|
||||
ChfPushHandler( CHF_NULL_HANDLER, _chf_sigjmp_buf, CHF_NULL_POINTER );
|
||||
|
||||
#define ChfCatch \
|
||||
ChfPopHandler();\
|
||||
}\
|
||||
else\
|
||||
#define ChfCatch \
|
||||
ChfPopHandler(); \
|
||||
} \
|
||||
else \
|
||||
{
|
||||
|
||||
#define ChfEndTry \
|
||||
ChfDiscard();\
|
||||
}\
|
||||
}
|
||||
|
||||
#define ChfEndTry \
|
||||
ChfDiscard(); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Other macros
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define ChfGetNextDescriptor(d) (d)->next
|
||||
#define ChfGetModuleId(d) (d)->module_id
|
||||
#define ChfGetConditionCode(d) (d)->condition_code
|
||||
#define ChfGetSeverity(d) (d)->severity
|
||||
#define ChfGetLineNumber(d) (d)->line_number
|
||||
#define ChfGetFileName(d) (d)->file_name
|
||||
#define ChfGetPartialMessage(d) (d)->message
|
||||
|
||||
|
||||
#define ChfGetNextDescriptor( d ) ( d )->next
|
||||
#define ChfGetModuleId( d ) ( d )->module_id
|
||||
#define ChfGetConditionCode( d ) ( d )->condition_code
|
||||
#define ChfGetSeverity( d ) ( d )->severity
|
||||
#define ChfGetLineNumber( d ) ( d )->line_number
|
||||
#define ChfGetFileName( d ) ( d )->file_name
|
||||
#define ChfGetPartialMessage( d ) ( d )->message
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int ChfInit( /* Generic initialization */
|
||||
const ChfChar *app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
void *mrs_data, /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit, /* 'Exit' function */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
int ChfInit( /* Generic initialization */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
void* mrs_data, /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit, /* 'Exit' function */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
);
|
||||
|
||||
int ChfMsgcatInit( /* Initialization with msgcat subsystem */
|
||||
const ChfChar *app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfChar *msgcat_name, /* Name of the message catalog */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
int ChfMsgcatInit( /* Initialization with msgcat subsystem */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfChar* msgcat_name, /* Name of the message catalog */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
);
|
||||
|
||||
int ChfStaticInit( /* Initialization with static message tables */
|
||||
const ChfChar *app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfTable *table, /* Static message table */
|
||||
const size_t table_size, /* Size of the message table */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
int ChfStaticInit( /* Initialization with static message tables */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfTable* table, /* Static message table */
|
||||
const size_t table_size, /* Size of the message table */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
);
|
||||
|
||||
int ChfWin32Init( /* Initialization within _WIN32 */
|
||||
const ChfChar *app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
int ChfWin32Init( /* Initialization within _WIN32 */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
#ifndef _WIN32
|
||||
void *instance, /* Fake arguments */
|
||||
void* instance, /* Fake arguments */
|
||||
#else
|
||||
HINSTANCE instance, /* App. instance handle */
|
||||
HINSTANCE instance, /* App. instance handle */
|
||||
#endif
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
);
|
||||
|
||||
void ChfExit( /* Exit */
|
||||
void
|
||||
void ChfExit( /* Exit */
|
||||
void );
|
||||
|
||||
void ChfAbort( /* Abort application */
|
||||
const int abort_code );
|
||||
|
||||
void ChfPushHandler( /* Push a new handler into the stack */
|
||||
ChfHandler new_handler, /* Handler to be added */
|
||||
void* unwind_context, /* Unwind context */
|
||||
ChfPointer handler_context /* Private handler context */
|
||||
);
|
||||
|
||||
void ChfAbort( /* Abort application */
|
||||
const int abort_code
|
||||
);
|
||||
void ChfPopHandler( /* Pop a handler */
|
||||
void );
|
||||
|
||||
void ChfPushHandler( /* Push a new handler into the stack */
|
||||
ChfHandler new_handler, /* Handler to be added */
|
||||
void *unwind_context, /* Unwind context */
|
||||
ChfPointer handler_context /* Private handler context */
|
||||
);
|
||||
ChfChar* ChfBuildMessage( /* Build a condition message */
|
||||
const ChfDescriptor* descriptor );
|
||||
|
||||
void ChfPopHandler( /* Pop a handler */
|
||||
void
|
||||
);
|
||||
void ChfSignal( /* Signal the current conditions */
|
||||
void );
|
||||
|
||||
ChfChar *ChfBuildMessage( /* Build a condition message */
|
||||
const ChfDescriptor *descriptor
|
||||
);
|
||||
void ChfDiscard( /* Discard the current conditions */
|
||||
void );
|
||||
|
||||
void ChfSignal( /* Signal the current conditions */
|
||||
void
|
||||
);
|
||||
void ChfGenerate( /* Generate a condition into the stack */
|
||||
const int module_id, const ChfChar* file_name, const int line_number, const int condition_code,
|
||||
const ChfSeverity severity, ... );
|
||||
|
||||
void ChfDiscard( /* Discard the current conditions */
|
||||
void
|
||||
);
|
||||
const ChfChar* ChfGetMessage( /* Retrieve a condition message */
|
||||
const int module_id, const int condition_code, const ChfChar* default_message );
|
||||
|
||||
void ChfGenerate( /* Generate a condition into the stack */
|
||||
const int module_id,
|
||||
const ChfChar *file_name,
|
||||
const int line_number,
|
||||
const int condition_code,
|
||||
const ChfSeverity severity,
|
||||
...
|
||||
);
|
||||
|
||||
const ChfChar *ChfGetMessage( /* Retrieve a condition message */
|
||||
const int module_id,
|
||||
const int condition_code,
|
||||
const ChfChar *default_message
|
||||
);
|
||||
|
||||
const ChfDescriptor *ChfGetTopCondition( /* Retrieve top condition */
|
||||
void
|
||||
);
|
||||
const ChfDescriptor* ChfGetTopCondition( /* Retrieve top condition */
|
||||
void );
|
||||
|
|
|
@ -37,119 +37,110 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define CHF_MODULE_ID CHF_SET
|
||||
#define CHF_TMP_MESSAGE_LENGTH (2*CHF_MAX_MESSAGE_LENGTH)
|
||||
#define CHF_DEF_MESSAGE_LENGTH 40
|
||||
#define CHF_DEF_PARTIAL_MSG_FMT ChfText("Code <%d>d")
|
||||
#define CHF_DEF_MID_MSG_FMT ChfText("Mid <%d>d")
|
||||
#define CHF_EXTENDED_INFO_FMT ChfText("(%s,%d)")
|
||||
#define CHF_SEVERITY_NAMES \
|
||||
{ ChfText("S"), ChfText("I"), ChfText("W"), ChfText("E"), ChfText("F") }
|
||||
#define CHF_UNKNOWN_SEVERITY ChfText("?")
|
||||
#define CHF_MESSAGE_SEPARATOR ChfText("-")
|
||||
#define CHF_MESSAGE_TERMINATOR ChfText("\n")
|
||||
#define CHF_ABORT_HEADER ChfText("ChfAbort-F-")
|
||||
#define CHF_ABORT_BAD_CODE_FMT ChfText("Bad abort code <%d>d\n")
|
||||
#define CHF_ABORT_GOOD_CODE_FMT ChfText("%s\n")
|
||||
|
||||
#define CHF_MODULE_ID CHF_SET
|
||||
#define CHF_TMP_MESSAGE_LENGTH ( 2 * CHF_MAX_MESSAGE_LENGTH )
|
||||
#define CHF_DEF_MESSAGE_LENGTH 40
|
||||
#define CHF_DEF_PARTIAL_MSG_FMT ChfText( "Code <%d>d" )
|
||||
#define CHF_DEF_MID_MSG_FMT ChfText( "Mid <%d>d" )
|
||||
#define CHF_EXTENDED_INFO_FMT ChfText( "(%s,%d)" )
|
||||
#define CHF_SEVERITY_NAMES \
|
||||
{ \
|
||||
ChfText( "S" ), ChfText( "I" ), ChfText( "W" ), ChfText( "E" ), ChfText( "F" ) \
|
||||
}
|
||||
#define CHF_UNKNOWN_SEVERITY ChfText( "?" )
|
||||
#define CHF_MESSAGE_SEPARATOR ChfText( "-" )
|
||||
#define CHF_MESSAGE_TERMINATOR ChfText( "\n" )
|
||||
#define CHF_ABORT_HEADER ChfText( "ChfAbort-F-" )
|
||||
#define CHF_ABORT_BAD_CODE_FMT ChfText( "Bad abort code <%d>d\n" )
|
||||
#define CHF_ABORT_GOOD_CODE_FMT ChfText( "%s\n" )
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Abort codes used with ChfAbort()
|
||||
Abort codes used with ChfAbort()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define CHF_ABORT_SILENT 0
|
||||
#define CHF_ABORT_INIT 1
|
||||
#define CHF_ABORT_MSG_OVF 2
|
||||
#define CHF_ABORT_INVALID_ACTION 3
|
||||
#define CHF_ABORT_DUP_INIT 4
|
||||
#define CHF_ABORT_ALREADY_UNWINDING 5
|
||||
#define CHF_ABORT_IMPROPERLY_HANDLED 6
|
||||
#define CHF_ABORT_FATAL_UNWINDING 7
|
||||
#define CHF_ABORT_COND_STACK_OVF 8
|
||||
#define CHF_ABORT_GET_CONTEXT 9
|
||||
#define CHF_ABORT_PTHREAD 10
|
||||
|
||||
|
||||
#define CHF_ABORT_SILENT 0
|
||||
#define CHF_ABORT_INIT 1
|
||||
#define CHF_ABORT_MSG_OVF 2
|
||||
#define CHF_ABORT_INVALID_ACTION 3
|
||||
#define CHF_ABORT_DUP_INIT 4
|
||||
#define CHF_ABORT_ALREADY_UNWINDING 5
|
||||
#define CHF_ABORT_IMPROPERLY_HANDLED 6
|
||||
#define CHF_ABORT_FATAL_UNWINDING 7
|
||||
#define CHF_ABORT_COND_STACK_OVF 8
|
||||
#define CHF_ABORT_GET_CONTEXT 9
|
||||
#define CHF_ABORT_PTHREAD 10
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Type definitions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct ChfHandlerDescriptor_S
|
||||
{
|
||||
ChfHandler handler;
|
||||
void *unwind_context;
|
||||
ChfPointer handler_context;
|
||||
}
|
||||
ChfHandlerDescriptor;
|
||||
typedef struct ChfHandlerDescriptor_S {
|
||||
ChfHandler handler;
|
||||
void* unwind_context;
|
||||
ChfPointer handler_context;
|
||||
} ChfHandlerDescriptor;
|
||||
|
||||
typedef struct ChfContext_S /* CHF Context */
|
||||
typedef struct ChfContext_S /* CHF Context */
|
||||
{
|
||||
ChfState state; /* Current CHF state */
|
||||
const ChfChar *app_name; /* Application's name */
|
||||
ChfOptions options; /* Options */
|
||||
void *mrs_data; /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get; /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit; /* 'Exit' function */
|
||||
int condition_stack_size; /* Size of the condition stack */
|
||||
int handler_stack_size; /* Size of the handler stack */
|
||||
int exit_code; /* Abnormal exit code */
|
||||
ChfDescriptor *condition_stack; /* Condition stack */
|
||||
ChfDescriptor *condition_base; /* Current condition stack base */
|
||||
ChfDescriptor *condition_sp; /* Current condition stack pointer */
|
||||
ChfHandlerDescriptor *handler_stack; /* Handler stack */
|
||||
ChfHandlerDescriptor *handler_sp; /* Current handler stack pointer */
|
||||
ChfChar *message_buffer; /* Message buffer */
|
||||
}
|
||||
ChfContext;
|
||||
|
||||
ChfState state; /* Current CHF state */
|
||||
const ChfChar* app_name; /* Application's name */
|
||||
ChfOptions options; /* Options */
|
||||
void* mrs_data; /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get; /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit; /* 'Exit' function */
|
||||
int condition_stack_size; /* Size of the condition stack */
|
||||
int handler_stack_size; /* Size of the handler stack */
|
||||
int exit_code; /* Abnormal exit code */
|
||||
ChfDescriptor* condition_stack; /* Condition stack */
|
||||
ChfDescriptor* condition_base; /* Current condition stack base */
|
||||
ChfDescriptor* condition_sp; /* Current condition stack pointer */
|
||||
ChfHandlerDescriptor* handler_stack; /* Handler stack */
|
||||
ChfHandlerDescriptor* handler_sp; /* Current handler stack pointer */
|
||||
ChfChar* message_buffer; /* Message buffer */
|
||||
} ChfContext;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Multithreading support
|
||||
------------------------------------------------------------------------- */
|
||||
#ifdef _REENTRANT
|
||||
#define chf_context (*_ChfGetContext())
|
||||
# define chf_context ( *_ChfGetContext() )
|
||||
#else
|
||||
#define chf_context _chf_context
|
||||
# define chf_context _chf_context
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Global variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
extern ChfContext _chf_context; /* CHF Context */
|
||||
|
||||
extern ChfContext _chf_context; /* CHF Context */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private function prototypes
|
||||
------------------------------------------------------------------------- */
|
||||
#ifdef _REENTRANT
|
||||
ChfContext *_ChfGetContext(void);
|
||||
ChfContext* _ChfGetContext( void );
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private redirection of stdlib functions needed by Win32
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef _WIN32
|
||||
#define ChfStrlen _tcslen
|
||||
#define ChfStrcpy _tcscpy
|
||||
#define ChfStrcat _tcscat
|
||||
#define ChfStrncpy _tcsncpy
|
||||
#define ChfSprintf _stprintf
|
||||
#define ChfVsprintf _vstprintf
|
||||
# define ChfStrlen _tcslen
|
||||
# define ChfStrcpy _tcscpy
|
||||
# define ChfStrcat _tcscat
|
||||
# define ChfStrncpy _tcsncpy
|
||||
# define ChfSprintf _stprintf
|
||||
# define ChfVsprintf _vstprintf
|
||||
#else
|
||||
#define ChfStrlen strlen
|
||||
#define ChfStrcpy strcpy
|
||||
#define ChfStrcat strcat
|
||||
#define ChfStrncpy strncpy
|
||||
#define ChfSprintf sprintf
|
||||
#define ChfVsprintf vsprintf
|
||||
# define ChfStrlen strlen
|
||||
# define ChfStrcpy strcpy
|
||||
# define ChfStrcat strcat
|
||||
# define ChfStrncpy strncpy
|
||||
# define ChfSprintf sprintf
|
||||
# define ChfVsprintf vsprintf
|
||||
#endif
|
||||
|
|
|
@ -37,43 +37,38 @@ static char rcs_id[] = "$Id: chf_abrt.c,v 2.2 2001/01/25 12:08:24 cibrario Exp $
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <setjmp.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
#ifdef _REENTRANT
|
||||
#include <pthread.h>
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Abort codes message table; the relative position of the messages must
|
||||
match the numeric codes CHF_ABORT_xxxx defined in ChfPriv.h
|
||||
*/
|
||||
static const ChfChar *message_table[] =
|
||||
{
|
||||
(const ChfChar *)NULL,
|
||||
ChfText("Not initialized"),
|
||||
ChfText("Temporary message buffer overflow"),
|
||||
ChfText("Invalid action from last chance handler"),
|
||||
ChfText("Already initialized"),
|
||||
ChfText("Unwind request while unwinding"),
|
||||
ChfText("Improperly handled condition"),
|
||||
ChfText("Fatal condition while unwinding"),
|
||||
ChfText("Condition stack overflow"),
|
||||
ChfText("Can't prime a new Chf context"),
|
||||
ChfText("Pthread interaction failed")
|
||||
};
|
||||
|
||||
#define MESSAGE_TABLE_SIZE (sizeof(message_table)/sizeof(const ChfChar *))
|
||||
static const ChfChar* message_table[] = { ( const ChfChar* )NULL,
|
||||
ChfText( "Not initialized" ),
|
||||
ChfText( "Temporary message buffer overflow" ),
|
||||
ChfText( "Invalid action from last chance handler" ),
|
||||
ChfText( "Already initialized" ),
|
||||
ChfText( "Unwind request while unwinding" ),
|
||||
ChfText( "Improperly handled condition" ),
|
||||
ChfText( "Fatal condition while unwinding" ),
|
||||
ChfText( "Condition stack overflow" ),
|
||||
ChfText( "Can't prime a new Chf context" ),
|
||||
ChfText( "Pthread interaction failed" ) };
|
||||
|
||||
#define MESSAGE_TABLE_SIZE ( sizeof( message_table ) / sizeof( const ChfChar* ) )
|
||||
|
||||
/* .+
|
||||
|
||||
|
@ -96,7 +91,7 @@ static const ChfChar *message_table[] =
|
|||
application when a CHF_FATAL condition occours.
|
||||
|
||||
NOTE: This function must be called only when either a serious internal CHF
|
||||
failure occurs or it's necessary to abort the application.
|
||||
failure occurs or it's necessary to abort the application.
|
||||
|
||||
WIN32:
|
||||
|
||||
|
@ -107,13 +102,13 @@ static const ChfChar *message_table[] =
|
|||
- abort() is not supported and has been replaced by exit(EXIT_FAILURE)
|
||||
|
||||
.call :
|
||||
ChfAbort(abort_code);
|
||||
ChfAbort(abort_code);
|
||||
.input :
|
||||
const int abort_code, abort_code
|
||||
const int abort_code, abort_code
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
none
|
||||
none
|
||||
.notes :
|
||||
1.1, 13-May-1996, creation
|
||||
2.1, 19-May-2000, update:
|
||||
|
@ -122,78 +117,66 @@ static const ChfChar *message_table[] =
|
|||
- added Win32 support
|
||||
|
||||
.- */
|
||||
void ChfAbort( /* Abort application */
|
||||
const int abort_code
|
||||
)
|
||||
void ChfAbort( /* Abort application */
|
||||
const int abort_code )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if(abort_code != CHF_ABORT_SILENT)
|
||||
{
|
||||
TCHAR abort_msg[CHF_MAX_MESSAGE_LENGTH];
|
||||
HWND active_window;
|
||||
if ( abort_code != CHF_ABORT_SILENT ) {
|
||||
TCHAR abort_msg[ CHF_MAX_MESSAGE_LENGTH ];
|
||||
HWND active_window;
|
||||
|
||||
/* stderr not available;
|
||||
put complaint in a message box and display it
|
||||
/* stderr not available;
|
||||
put complaint in a message box and display it
|
||||
*/
|
||||
if ( abort_code < 0 || abort_code >= MESSAGE_TABLE_SIZE )
|
||||
_stprintf( abort_msg, CHF_ABORT_BAD_CODE_FMT, abort_code );
|
||||
|
||||
else
|
||||
_stprintf( abort_msg, CHF_ABORT_GOOD_CODE_FMT, message_table[ abort_code ] );
|
||||
|
||||
/* Return value of MessageBox() ignored, because there is only
|
||||
one available choice (abort) here. Avoid using a NULL handle.
|
||||
*/
|
||||
if ( chf_context.state != CHF_UNKNOWN && ( active_window = GetActiveWindow() ) != ( HWND )NULL )
|
||||
( void )MessageBox( active_window, abort_msg, chf_context.app_name, MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND );
|
||||
}
|
||||
|
||||
/* Immediately exit the application with exit code EXIT_FAILURE
|
||||
if CHF_ABORT option is set or if something is wrong with Chf state.
|
||||
*/
|
||||
if(abort_code < 0 || abort_code >= MESSAGE_TABLE_SIZE)
|
||||
_stprintf(abort_msg,
|
||||
CHF_ABORT_BAD_CODE_FMT, abort_code);
|
||||
if ( chf_context.state == CHF_UNKNOWN || chf_context.options & CHF_ABORT )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
else
|
||||
_stprintf(abort_msg,
|
||||
CHF_ABORT_GOOD_CODE_FMT, message_table[abort_code]);
|
||||
|
||||
/* Return value of MessageBox() ignored, because there is only
|
||||
one available choice (abort) here. Avoid using a NULL handle.
|
||||
*/
|
||||
if(chf_context.state != CHF_UNKNOWN
|
||||
&& (active_window = GetActiveWindow()) != (HWND)NULL)
|
||||
(void)
|
||||
MessageBox(active_window,
|
||||
abort_msg,
|
||||
chf_context.app_name,
|
||||
MB_OK
|
||||
|MB_ICONERROR
|
||||
|MB_APPLMODAL|MB_SETFOREGROUND);
|
||||
}
|
||||
|
||||
/* Immediately exit the application with exit code EXIT_FAILURE
|
||||
if CHF_ABORT option is set or if something is wrong with Chf state.
|
||||
*/
|
||||
if(chf_context.state == CHF_UNKNOWN || chf_context.options & CHF_ABORT)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
else
|
||||
/* Else, exit the application anyway, but with the exit code
|
||||
registered by the application. Don't use PostQuitMessage(),
|
||||
because the contract is that ChfAbort() never returns to the caller.
|
||||
*/
|
||||
#ifndef _REENTRANT
|
||||
exit(chf_context.exit_code);
|
||||
#else
|
||||
#error "_REENTRANT not supported yet"
|
||||
#endif
|
||||
# ifndef _REENTRANT
|
||||
exit( chf_context.exit_code );
|
||||
# else
|
||||
# error "_REENTRANT not supported yet"
|
||||
# endif
|
||||
|
||||
#else
|
||||
if(abort_code != CHF_ABORT_SILENT)
|
||||
{
|
||||
fputs(CHF_ABORT_HEADER, stderr);
|
||||
if ( abort_code != CHF_ABORT_SILENT ) {
|
||||
fputs( CHF_ABORT_HEADER, stderr );
|
||||
|
||||
if(abort_code < 0 || abort_code >= MESSAGE_TABLE_SIZE)
|
||||
fprintf(stderr, CHF_ABORT_BAD_CODE_FMT, abort_code);
|
||||
if ( abort_code < 0 || abort_code >= MESSAGE_TABLE_SIZE )
|
||||
fprintf( stderr, CHF_ABORT_BAD_CODE_FMT, abort_code );
|
||||
|
||||
else
|
||||
fprintf( stderr, CHF_ABORT_GOOD_CODE_FMT, message_table[ abort_code ] );
|
||||
}
|
||||
|
||||
if ( chf_context.state == CHF_UNKNOWN || chf_context.options & CHF_ABORT )
|
||||
abort();
|
||||
|
||||
else
|
||||
fprintf(stderr, CHF_ABORT_GOOD_CODE_FMT, message_table[abort_code]);
|
||||
}
|
||||
|
||||
if(chf_context.state == CHF_UNKNOWN || chf_context.options & CHF_ABORT)
|
||||
abort();
|
||||
|
||||
else
|
||||
#ifndef _REENTRANT
|
||||
exit(chf_context.exit_code);
|
||||
#else
|
||||
pthread_exit((void *)(chf_context.exit_code));
|
||||
#endif
|
||||
# ifndef _REENTRANT
|
||||
exit( chf_context.exit_code );
|
||||
# else
|
||||
pthread_exit( ( void* )( chf_context.exit_code ) );
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -31,21 +31,20 @@ static char rcs_id[] = "$Id: chf_gen.c,v 2.2 2001/01/25 12:10:22 cibrario Exp $"
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfGenerate
|
||||
|
@ -63,117 +62,104 @@ static char rcs_id[] = "$Id: chf_gen.c,v 2.2 2001/01/25 12:10:22 cibrario Exp $"
|
|||
condition stack.
|
||||
|
||||
NOTE: This function calls the CHF function 'ChfAbort()' to
|
||||
abort the application if either:
|
||||
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
||||
- there is an overflow in the internal buffer used during the
|
||||
generation of the partial message associated with the condition
|
||||
(abort code CHF_ABORT_MSG_OVF)
|
||||
- there was an attempt to generate a condition while the CHF condition
|
||||
CHF_F_COND_STACK_FULL (condition stack full) was being signalled
|
||||
(abort code CHF_ABORT_COND_STACK_OVF)
|
||||
abort the application if either:
|
||||
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
||||
- there is an overflow in the internal buffer used during the
|
||||
generation of the partial message associated with the condition
|
||||
(abort code CHF_ABORT_MSG_OVF)
|
||||
- there was an attempt to generate a condition while the CHF condition
|
||||
CHF_F_COND_STACK_FULL (condition stack full) was being signalled
|
||||
(abort code CHF_ABORT_COND_STACK_OVF)
|
||||
|
||||
|
||||
.call :
|
||||
ChfGenerate(module_id, file_name, line_number,
|
||||
condition_code, severity, ...);
|
||||
ChfGenerate(module_id, file_name, line_number,
|
||||
condition_code, severity, ...);
|
||||
.input :
|
||||
const int module_id, module identifier
|
||||
const char *file_name, file name
|
||||
const int line_number, line number
|
||||
const int condition_code, condition code
|
||||
const ChfSeverity severity, severity
|
||||
..., additional arguments
|
||||
const int module_id, module identifier
|
||||
const char *file_name, file name
|
||||
const int line_number, line number
|
||||
const int condition_code, condition code
|
||||
const ChfSeverity severity, severity
|
||||
..., additional arguments
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
(*) CHF_F_COND_STACK_FULL, the condition stack is full
|
||||
(*) CHF_F_COND_STACK_FULL, the condition stack is full
|
||||
.notes :
|
||||
1.1, 3-May-1996, creation
|
||||
|
||||
.- */
|
||||
void ChfGenerate( /* Generate a condition into the stack */
|
||||
const int module_id,
|
||||
const ChfChar *file_name,
|
||||
const int line_number,
|
||||
const int condition_code,
|
||||
const ChfSeverity severity,
|
||||
...
|
||||
)
|
||||
void ChfGenerate( /* Generate a condition into the stack */
|
||||
const int module_id, const ChfChar* file_name, const int line_number, const int condition_code,
|
||||
const ChfSeverity severity, ... )
|
||||
{
|
||||
ChfDescriptor *new_descriptor;
|
||||
va_list aux_arg;
|
||||
ChfDescriptor* new_descriptor;
|
||||
va_list aux_arg;
|
||||
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
/* Prepare the additional arguments list */
|
||||
va_start(aux_arg, severity);
|
||||
/* Prepare the additional arguments list */
|
||||
va_start( aux_arg, severity );
|
||||
|
||||
if((new_descriptor = chf_context.condition_sp) -
|
||||
chf_context.condition_stack >= chf_context.condition_stack_size)
|
||||
{
|
||||
/* The condition stack is full;
|
||||
generate the CHF_F_COND_STACK_FULL condition and signal it immediately,
|
||||
using the last available slot of the stack, if it's still empty,
|
||||
otherwise abort the application.
|
||||
*/
|
||||
if(new_descriptor - chf_context.condition_stack ==
|
||||
chf_context.condition_stack_size)
|
||||
{
|
||||
new_descriptor->module_id = CHF_MODULE_ID;
|
||||
new_descriptor->condition_code = CHF_F_COND_STACK_FULL;
|
||||
new_descriptor->severity = CHF_FATAL;
|
||||
new_descriptor->line_number = CHF_UNKNOWN_LINE_NUMBER;
|
||||
new_descriptor->file_name = CHF_UNKNOWN_FILE_NAME;
|
||||
if ( ( new_descriptor = chf_context.condition_sp ) - chf_context.condition_stack >= chf_context.condition_stack_size ) {
|
||||
/* The condition stack is full;
|
||||
generate the CHF_F_COND_STACK_FULL condition and signal it immediately,
|
||||
using the last available slot of the stack, if it's still empty,
|
||||
otherwise abort the application.
|
||||
*/
|
||||
if ( new_descriptor - chf_context.condition_stack == chf_context.condition_stack_size ) {
|
||||
new_descriptor->module_id = CHF_MODULE_ID;
|
||||
new_descriptor->condition_code = CHF_F_COND_STACK_FULL;
|
||||
new_descriptor->severity = CHF_FATAL;
|
||||
new_descriptor->line_number = CHF_UNKNOWN_LINE_NUMBER;
|
||||
new_descriptor->file_name = CHF_UNKNOWN_FILE_NAME;
|
||||
|
||||
ChfStrncpy(new_descriptor->message,
|
||||
ChfGetMessage(CHF_MODULE_ID, CHF_F_COND_STACK_FULL,
|
||||
ChfText("Condition stack is full")), CHF_MAX_MESSAGE_LENGTH-1);
|
||||
new_descriptor->message[CHF_MAX_MESSAGE_LENGTH-1] = '\0';
|
||||
ChfStrncpy( new_descriptor->message,
|
||||
ChfGetMessage( CHF_MODULE_ID, CHF_F_COND_STACK_FULL, ChfText( "Condition stack is full" ) ),
|
||||
CHF_MAX_MESSAGE_LENGTH - 1 );
|
||||
new_descriptor->message[ CHF_MAX_MESSAGE_LENGTH - 1 ] = '\0';
|
||||
|
||||
new_descriptor->next = CHF_NULL_DESCRIPTOR;
|
||||
chf_context.condition_sp++;
|
||||
new_descriptor->next = CHF_NULL_DESCRIPTOR;
|
||||
chf_context.condition_sp++;
|
||||
|
||||
ChfSignal();
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else
|
||||
ChfAbort( CHF_ABORT_COND_STACK_OVF );
|
||||
}
|
||||
|
||||
else
|
||||
ChfAbort(CHF_ABORT_COND_STACK_OVF);
|
||||
}
|
||||
else {
|
||||
ChfChar def_message[ CHF_DEF_MESSAGE_LENGTH ];
|
||||
ChfChar tmp_message[ CHF_TMP_MESSAGE_LENGTH ];
|
||||
|
||||
else
|
||||
{
|
||||
ChfChar def_message[CHF_DEF_MESSAGE_LENGTH];
|
||||
ChfChar tmp_message[CHF_TMP_MESSAGE_LENGTH];
|
||||
new_descriptor->module_id = module_id;
|
||||
new_descriptor->condition_code = condition_code;
|
||||
new_descriptor->severity = severity;
|
||||
new_descriptor->line_number = line_number;
|
||||
new_descriptor->file_name = file_name;
|
||||
|
||||
new_descriptor->module_id = module_id;
|
||||
new_descriptor->condition_code = condition_code;
|
||||
new_descriptor->severity = severity;
|
||||
new_descriptor->line_number = line_number;
|
||||
new_descriptor->file_name = file_name;
|
||||
/* Generate the default message */
|
||||
ChfSprintf( def_message, CHF_DEF_PARTIAL_MSG_FMT, condition_code );
|
||||
|
||||
/* Generate the default message */
|
||||
ChfSprintf(def_message, CHF_DEF_PARTIAL_MSG_FMT, condition_code);
|
||||
/* Generate the partial message associated with the condition using a
|
||||
temporary area
|
||||
*/
|
||||
if ( ChfVsprintf( tmp_message, ChfGetMessage( module_id, condition_code, def_message ), aux_arg ) >= CHF_TMP_MESSAGE_LENGTH )
|
||||
ChfAbort( CHF_ABORT_MSG_OVF );
|
||||
|
||||
/* Generate the partial message associated with the condition using a
|
||||
temporary area
|
||||
*/
|
||||
if(
|
||||
ChfVsprintf(tmp_message,
|
||||
ChfGetMessage(module_id, condition_code, def_message), aux_arg) >=
|
||||
CHF_TMP_MESSAGE_LENGTH)
|
||||
ChfAbort(CHF_ABORT_MSG_OVF);
|
||||
|
||||
/* Copy the message into the condition descriptor */
|
||||
ChfStrncpy(new_descriptor->message, tmp_message, CHF_MAX_MESSAGE_LENGTH-1);
|
||||
new_descriptor->message[CHF_MAX_MESSAGE_LENGTH-1] = '\0';
|
||||
/* Copy the message into the condition descriptor */
|
||||
ChfStrncpy( new_descriptor->message, tmp_message, CHF_MAX_MESSAGE_LENGTH - 1 );
|
||||
new_descriptor->message[ CHF_MAX_MESSAGE_LENGTH - 1 ] = '\0';
|
||||
|
||||
/* Link the new descriptor with the current descriptor list, if it
|
||||
isn't the first descriptor of the list
|
||||
*/
|
||||
new_descriptor->next = (new_descriptor == chf_context.condition_base)
|
||||
? CHF_NULL_DESCRIPTOR : new_descriptor - 1;
|
||||
/* Link the new descriptor with the current descriptor list, if it
|
||||
isn't the first descriptor of the list
|
||||
*/
|
||||
new_descriptor->next = ( new_descriptor == chf_context.condition_base ) ? CHF_NULL_DESCRIPTOR : new_descriptor - 1;
|
||||
|
||||
chf_context.condition_sp++;
|
||||
}
|
||||
chf_context.condition_sp++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,19 +44,18 @@ static char rcs_id[] = "$Id: chf_hdlr.c,v 2.2 2001/01/25 12:12:46 cibrario Exp $
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <setjmp.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : StructuredHelper
|
||||
|
@ -68,42 +67,36 @@ static char rcs_id[] = "$Id: chf_hdlr.c,v 2.2 2001/01/25 12:12:46 cibrario Exp $
|
|||
ChfPushHandler() when its 'new_handler' argument is CHF_NULL_HANDLER,
|
||||
and performs the following functions:
|
||||
|
||||
- if called during an ordinary signalling operation with a
|
||||
CHF_FATAL condition, it requests the action CHF_UNWIND_KEEP
|
||||
- if called during an ordinary signalling operation with a
|
||||
CHF_FATAL condition, it requests the action CHF_UNWIND_KEEP
|
||||
|
||||
- if called when Chf is in any other state, or with a
|
||||
severity less than CHF_FATAL, it requests the action CHF_RESIGNAL
|
||||
- if called when Chf is in any other state, or with a
|
||||
severity less than CHF_FATAL, it requests the action CHF_RESIGNAL
|
||||
|
||||
The structured condition handling helper currently makes no use of
|
||||
handler_context.
|
||||
|
||||
.call :
|
||||
action = StructuredHelper(desc, state, context);
|
||||
action = StructuredHelper(desc, state, context);
|
||||
.input :
|
||||
const ChfDescriptor *desc, condition descriptor
|
||||
const ChfState state, current CHF state
|
||||
const ChfDescriptor *desc, condition descriptor
|
||||
const ChfState state, current CHF state
|
||||
.output :
|
||||
ChfAction action, action requested by the handler
|
||||
ChfAction action, action requested by the handler
|
||||
.status_codes :
|
||||
none
|
||||
none
|
||||
.notes :
|
||||
2.1, 19-May-2000, creation
|
||||
|
||||
.- */
|
||||
static ChfAction StructuredHelper(
|
||||
const ChfDescriptor *desc,
|
||||
const ChfState state,
|
||||
ChfPointer handler_context
|
||||
)
|
||||
static ChfAction StructuredHelper( const ChfDescriptor* desc, const ChfState state, ChfPointer handler_context )
|
||||
{
|
||||
ChfAction action;
|
||||
const ChfDescriptor *d;
|
||||
ChfAction action;
|
||||
const ChfDescriptor* d;
|
||||
|
||||
return((state == CHF_SIGNALING && ChfGetSeverity(desc) == CHF_FATAL)
|
||||
? CHF_UNWIND_KEEP : CHF_RESIGNAL);
|
||||
return ( ( state == CHF_SIGNALING && ChfGetSeverity( desc ) == CHF_FATAL ) ? CHF_UNWIND_KEEP : CHF_RESIGNAL );
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfPushHandler
|
||||
|
@ -123,7 +116,7 @@ static ChfAction StructuredHelper(
|
|||
remain valid until 'new_handler' is popped from the condition stack.
|
||||
'handler_context' may be set to the special (null) value CHF_NULL_POINTER to
|
||||
indicate that the handler hasn't any private context information.
|
||||
|
||||
|
||||
If, in the future, the handler will request the CHF_UNWIND action, the
|
||||
setjmp() function invocation that established 'unwind_context' will appear
|
||||
to return again.
|
||||
|
@ -139,19 +132,19 @@ static ChfAction StructuredHelper(
|
|||
conditions are CHF_FATAL.
|
||||
|
||||
NOTE: This function calls ChfAbort() with abort code CHF_ABORT_INIT if
|
||||
the CHF subsystem has not been initialized.
|
||||
the CHF subsystem has not been initialized.
|
||||
|
||||
.call :
|
||||
ChfPushHandler(new_handler, unwind_context);
|
||||
ChfPushHandler(new_handler, unwind_context);
|
||||
.input :
|
||||
ChfHandler new_handler, new condition handler
|
||||
void *unwind_context, handler unwind context pointer
|
||||
ChfPointer handler_context, private handler context pointer
|
||||
ChfHandler new_handler, new condition handler
|
||||
void *unwind_context, handler unwind context pointer
|
||||
ChfPointer handler_context, private handler context pointer
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
(*) CHF_F_BAD_STATE, bad CHF state for requested operation
|
||||
(*) CHF_F_HDLR_STACK_FULL, the handler stack is full
|
||||
(*) CHF_F_BAD_STATE, bad CHF state for requested operation
|
||||
(*) CHF_F_HDLR_STACK_FULL, the handler stack is full
|
||||
.notes :
|
||||
1.1, 13-May-1996, creation
|
||||
1.6, 15-Jan-1997, update:
|
||||
|
@ -162,44 +155,34 @@ static ChfAction StructuredHelper(
|
|||
- added StructuredHelper handling
|
||||
|
||||
.- */
|
||||
void ChfPushHandler( /* Push a new handler into the stack */
|
||||
ChfHandler new_handler,
|
||||
void *unwind_context,
|
||||
ChfPointer handler_context
|
||||
)
|
||||
void ChfPushHandler( /* Push a new handler into the stack */
|
||||
ChfHandler new_handler, void* unwind_context, ChfPointer handler_context )
|
||||
{
|
||||
/* Make sure that CHF has been correctly initialized and is idle */
|
||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
||||
/* Make sure that CHF has been correctly initialized and is idle */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
if(chf_context.state != CHF_IDLE)
|
||||
{
|
||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL
|
||||
ChfEnd;
|
||||
if ( chf_context.state != CHF_IDLE ) {
|
||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Check if the handler stack is full */
|
||||
else if(chf_context.handler_sp - chf_context.handler_stack >=
|
||||
chf_context.handler_stack_size)
|
||||
{
|
||||
ChfCondition CHF_F_HDLR_STACK_FULL, CHF_FATAL
|
||||
ChfEnd;
|
||||
/* Check if the handler stack is full */
|
||||
else if ( chf_context.handler_sp - chf_context.handler_stack >= chf_context.handler_stack_size ) {
|
||||
ChfCondition CHF_F_HDLR_STACK_FULL, CHF_FATAL ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
chf_context.handler_sp->unwind_context = unwind_context;
|
||||
chf_context.handler_sp->handler_context = handler_context;
|
||||
chf_context.handler_sp->handler =
|
||||
((new_handler == CHF_NULL_HANDLER) ? StructuredHelper : new_handler);
|
||||
chf_context.handler_sp++;
|
||||
}
|
||||
else {
|
||||
chf_context.handler_sp->unwind_context = unwind_context;
|
||||
chf_context.handler_sp->handler_context = handler_context;
|
||||
chf_context.handler_sp->handler = ( ( new_handler == CHF_NULL_HANDLER ) ? StructuredHelper : new_handler );
|
||||
chf_context.handler_sp++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfPopHandler
|
||||
|
@ -208,24 +191,24 @@ void ChfPushHandler( /* Push a new handler into the stack */
|
|||
.description :
|
||||
This function pops the topmost condition handler from the handler stack and
|
||||
returns to the caller.
|
||||
|
||||
|
||||
If some error occours during the execution, the function will generate
|
||||
and immediately signal one of the conditions listed below and marked with
|
||||
(*). The function will never return directly to the caller, since all
|
||||
conditions are CHF_FATAL.
|
||||
|
||||
NOTE: This function calls ChfAbort() with abort code CHF_ABORT_INIT if
|
||||
the CHF subsystem has not been initialized.
|
||||
the CHF subsystem has not been initialized.
|
||||
|
||||
.call :
|
||||
ChfPopHandler();
|
||||
ChfPopHandler();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
CHF_F_BAD_STATE, bad CHF state for requested operation
|
||||
CHF_F_HDLR_STACK_FULL, the handler stack is full
|
||||
CHF_F_BAD_STATE, bad CHF state for requested operation
|
||||
CHF_F_HDLR_STACK_FULL, the handler stack is full
|
||||
.notes :
|
||||
1.1, 13-May-1996, creation
|
||||
1.6, 15-Jan-1997, update:
|
||||
|
@ -234,31 +217,27 @@ void ChfPushHandler( /* Push a new handler into the stack */
|
|||
- improved documentation
|
||||
|
||||
.- */
|
||||
void ChfPopHandler( /* Pop a handler */
|
||||
void
|
||||
)
|
||||
void ChfPopHandler( /* Pop a handler */
|
||||
void )
|
||||
{
|
||||
/* Make sure that CHF has been correctly initialized and is idle */
|
||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
||||
/* Make sure that CHF has been correctly initialized and is idle */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
if(chf_context.state != CHF_IDLE)
|
||||
{
|
||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL
|
||||
ChfEnd;
|
||||
if ( chf_context.state != CHF_IDLE ) {
|
||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Check if the handler stack is empty */
|
||||
else if(chf_context.handler_sp == chf_context.handler_stack)
|
||||
{
|
||||
ChfCondition CHF_F_HDLR_STACK_EMPTY, CHF_FATAL
|
||||
ChfEnd;
|
||||
/* Check if the handler stack is empty */
|
||||
else if ( chf_context.handler_sp == chf_context.handler_stack ) {
|
||||
ChfCondition CHF_F_HDLR_STACK_EMPTY, CHF_FATAL ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Discard the topmost condition handler */
|
||||
else
|
||||
--chf_context.handler_sp;
|
||||
/* Discard the topmost condition handler */
|
||||
else
|
||||
--chf_context.handler_sp;
|
||||
}
|
||||
|
|
|
@ -54,20 +54,19 @@ static char rcs_id[] = "$Id: chf_init.c,v 2.2 2001/01/25 14:05:23 cibrario Exp $
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Global and static variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -82,14 +81,13 @@ ChfContext _chf_context;
|
|||
|
||||
/* Message separator and severity names for ChfBuildMessage() */
|
||||
static const ChfChar separator[] = CHF_MESSAGE_SEPARATOR;
|
||||
static const ChfChar *severity_name[] = CHF_SEVERITY_NAMES;
|
||||
|
||||
static const ChfChar* severity_name[] = CHF_SEVERITY_NAMES;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Multithreading support
|
||||
------------------------------------------------------------------------- */
|
||||
#ifdef _REENTRANT
|
||||
#include <pthread.h>
|
||||
# include <pthread.h>
|
||||
|
||||
/* Mutex to access chf_context during initialization and exit;
|
||||
mutex to puts condition messages on stderr (DefaultHandler)
|
||||
|
@ -103,21 +101,19 @@ static pthread_key_t data_key;
|
|||
/* This function is called to destroy a Chf context when the owning
|
||||
thread terminated.
|
||||
*/
|
||||
static void DestroyContext(void *context)
|
||||
static void DestroyContext( void* context )
|
||||
{
|
||||
free(((ChfContext *)context)->message_buffer);
|
||||
free(((ChfContext *)context)->handler_stack);
|
||||
free(((ChfContext *)context)->condition_stack);
|
||||
free(context);
|
||||
free( ( ( ChfContext* )context )->message_buffer );
|
||||
free( ( ( ChfContext* )context )->handler_stack );
|
||||
free( ( ( ChfContext* )context )->condition_stack );
|
||||
free( context );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : DefaultHandler
|
||||
|
@ -128,21 +124,21 @@ static void DestroyContext(void *context)
|
|||
pushed into the condition handler stack by ChfInit() and performs the
|
||||
following functions:
|
||||
|
||||
- if called during an unwind, it returns immediately to the caller,
|
||||
requesting the action CHF_RESIGNAL, else
|
||||
- if called during an unwind, it returns immediately to the caller,
|
||||
requesting the action CHF_RESIGNAL, else
|
||||
|
||||
- if the severity of the condition being signalled is greater than
|
||||
CHF_SUCCESS, it prints the messages associated with the entire
|
||||
condition group on stderr using the standard function
|
||||
ChfBuildMessage() to build the messages.
|
||||
- if the severity of the condition being signalled is greater than
|
||||
CHF_SUCCESS, it prints the messages associated with the entire
|
||||
condition group on stderr using the standard function
|
||||
ChfBuildMessage() to build the messages.
|
||||
|
||||
- if the severity of the condition being signalled is less than
|
||||
CHF_FATAL, it returns to the caller requesting the action
|
||||
CHF_CONTINUE, else
|
||||
- if the severity of the condition being signalled is less than
|
||||
CHF_FATAL, it returns to the caller requesting the action
|
||||
CHF_CONTINUE, else
|
||||
|
||||
- if the CHF_FATAL condition was NOT signalled during an unwind
|
||||
operation, it returns to the caller requesting the action
|
||||
CHF_UNWIND, otherwise it requests the action CHF_RESIGNAL.
|
||||
- if the CHF_FATAL condition was NOT signalled during an unwind
|
||||
operation, it returns to the caller requesting the action
|
||||
CHF_UNWIND, otherwise it requests the action CHF_RESIGNAL.
|
||||
|
||||
WIN32:
|
||||
|
||||
|
@ -151,14 +147,14 @@ static void DestroyContext(void *context)
|
|||
anything
|
||||
|
||||
.call :
|
||||
action = DefaultHandler(desc, state, context);
|
||||
action = DefaultHandler(desc, state, context);
|
||||
.input :
|
||||
const ChfDescriptor *desc, condition descriptor
|
||||
const ChfState state, current CHF state
|
||||
const ChfDescriptor *desc, condition descriptor
|
||||
const ChfState state, current CHF state
|
||||
.output :
|
||||
ChfAction action, action requested by the handler
|
||||
ChfAction action, action requested by the handler
|
||||
.status_codes :
|
||||
none
|
||||
none
|
||||
.notes :
|
||||
1.1, 16-May-1996, creation
|
||||
1.6, 15-Jan-1997, update:
|
||||
|
@ -170,69 +166,62 @@ static void DestroyContext(void *context)
|
|||
- added Win32 support
|
||||
|
||||
.- */
|
||||
static ChfAction DefaultHandler(
|
||||
const ChfDescriptor *desc,
|
||||
const ChfState state,
|
||||
ChfPointer handler_context
|
||||
)
|
||||
static ChfAction DefaultHandler( const ChfDescriptor* desc, const ChfState state, ChfPointer handler_context )
|
||||
{
|
||||
ChfAction action;
|
||||
const ChfDescriptor *d;
|
||||
ChfAction action;
|
||||
const ChfDescriptor* d;
|
||||
|
||||
if(state == CHF_UNWINDING)
|
||||
/* If CHF is unwinding, do nothing */
|
||||
action = CHF_RESIGNAL;
|
||||
if ( state == CHF_UNWINDING )
|
||||
/* If CHF is unwinding, do nothing */
|
||||
action = CHF_RESIGNAL;
|
||||
|
||||
else
|
||||
{
|
||||
/* Print the condition messages, if necessary. The sequence of fputs()
|
||||
is done atomically if multithreading support is enabled.
|
||||
In Win32, the default handler does not print anything.
|
||||
*/
|
||||
if(ChfGetSeverity(desc) > CHF_SUCCESS)
|
||||
{
|
||||
else {
|
||||
/* Print the condition messages, if necessary. The sequence of fputs()
|
||||
is done atomically if multithreading support is enabled.
|
||||
In Win32, the default handler does not print anything.
|
||||
*/
|
||||
if ( ChfGetSeverity( desc ) > CHF_SUCCESS ) {
|
||||
#ifdef _REENTRANT
|
||||
if(pthread_mutex_lock(&fputs_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
||||
if ( pthread_mutex_lock( &fputs_mutex ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
for(d = desc; d != CHF_NULL_DESCRIPTOR; d = ChfGetNextDescriptor(d))
|
||||
fputs(ChfBuildMessage(d), stderr);
|
||||
for ( d = desc; d != CHF_NULL_DESCRIPTOR; d = ChfGetNextDescriptor( d ) )
|
||||
fputs( ChfBuildMessage( d ), stderr );
|
||||
#endif
|
||||
#ifdef _REENTRANT
|
||||
if(pthread_mutex_unlock(&fputs_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
||||
if ( pthread_mutex_unlock( &fputs_mutex ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Determine the handler action */
|
||||
switch ( ChfGetSeverity( desc ) ) {
|
||||
case CHF_SUCCESS:
|
||||
case CHF_INFO:
|
||||
case CHF_WARNING:
|
||||
case CHF_ERROR:
|
||||
{
|
||||
/* Continue execution if the severity is less than CHF_FATAL */
|
||||
action = CHF_CONTINUE;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
/* The severity of the condition is CHF_FATAL; appempt to unwind if
|
||||
the fatal condition wasn't signalled during another unwind.
|
||||
*/
|
||||
action = ( ( state == CHF_SIGNAL_UNWINDING ) ? CHF_RESIGNAL : CHF_UNWIND );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine the handler action */
|
||||
switch(ChfGetSeverity(desc))
|
||||
{
|
||||
case CHF_SUCCESS:
|
||||
case CHF_INFO:
|
||||
case CHF_WARNING:
|
||||
case CHF_ERROR:
|
||||
{
|
||||
/* Continue execution if the severity is less than CHF_FATAL */
|
||||
action = CHF_CONTINUE;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
/* The severity of the condition is CHF_FATAL; appempt to unwind if
|
||||
the fatal condition wasn't signalled during another unwind.
|
||||
*/
|
||||
action = ((state == CHF_SIGNAL_UNWINDING) ? CHF_RESIGNAL: CHF_UNWIND);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the action code to the Chf handler dispatcher */
|
||||
return action;
|
||||
/* Return the action code to the Chf handler dispatcher */
|
||||
return action;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : scopy
|
||||
|
@ -244,45 +233,38 @@ static ChfAction DefaultHandler(
|
|||
The function returns a pointer to the NUL-terminator just written.
|
||||
|
||||
.call :
|
||||
np = scopy(p, q, p_end);
|
||||
np = scopy(p, q, p_end);
|
||||
.input :
|
||||
char *p, starting position for the write
|
||||
const char *q, pointer to the string to be copied
|
||||
char *p_end, pointer to the end of the output area
|
||||
char *p, starting position for the write
|
||||
const char *q, pointer to the string to be copied
|
||||
char *p_end, pointer to the end of the output area
|
||||
.output :
|
||||
char *np, pointer to the NUL-terminator just written
|
||||
char *np, pointer to the NUL-terminator just written
|
||||
.status_codes :
|
||||
none
|
||||
none
|
||||
.notes :
|
||||
1.1, 16-May-1996, creation
|
||||
|
||||
.- */
|
||||
static ChfChar *scopy(
|
||||
ChfChar *p,
|
||||
const ChfChar *q,
|
||||
ChfChar *p_end
|
||||
)
|
||||
static ChfChar* scopy( ChfChar* p, const ChfChar* q, ChfChar* p_end )
|
||||
{
|
||||
size_t q_len = ChfStrlen(q);
|
||||
size_t p_avail = p_end - p;
|
||||
size_t q_len = ChfStrlen( q );
|
||||
size_t p_avail = p_end - p;
|
||||
|
||||
if(q_len < p_avail)
|
||||
{
|
||||
ChfStrcpy(p, q);
|
||||
p += q_len;
|
||||
}
|
||||
if ( q_len < p_avail ) {
|
||||
ChfStrcpy( p, q );
|
||||
p += q_len;
|
||||
}
|
||||
|
||||
else if(p_avail > 1)
|
||||
{
|
||||
ChfStrncpy(p, q, p_avail-2);
|
||||
p[p_avail-1] = '\0';
|
||||
p = p_end;
|
||||
}
|
||||
else if ( p_avail > 1 ) {
|
||||
ChfStrncpy( p, q, p_avail - 2 );
|
||||
p[ p_avail - 1 ] = '\0';
|
||||
p = p_end;
|
||||
}
|
||||
|
||||
return p;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Public functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -300,10 +282,10 @@ static ChfChar *scopy(
|
|||
necessary, to retrieve the requested message.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_INIT
|
||||
if CHF hasn't been correctly initialized.
|
||||
if CHF hasn't been correctly initialized.
|
||||
|
||||
NOTE: The returned pointer points to per-thread static storage, which will be
|
||||
overwritten by subsequent calls to this function.
|
||||
overwritten by subsequent calls to this function.
|
||||
|
||||
WIN32:
|
||||
|
||||
|
@ -311,46 +293,42 @@ static ChfChar *scopy(
|
|||
codes in CHF_ERRNO_SET is not performed
|
||||
|
||||
.call :
|
||||
message = ChfGetMessage(module_id, condition_code,
|
||||
default_message);
|
||||
message = ChfGetMessage(module_id, condition_code,
|
||||
default_message);
|
||||
.input :
|
||||
const int module_id, module identifier
|
||||
const int condition_code, condition code
|
||||
const char *default_message, default message
|
||||
const int module_id, module identifier
|
||||
const int condition_code, condition code
|
||||
const char *default_message, default message
|
||||
.output :
|
||||
const char *message, pointer to the retrieved message
|
||||
const char *message, pointer to the retrieved message
|
||||
.status_codes :
|
||||
none
|
||||
none
|
||||
.notes :
|
||||
1.1, 17-May-1996, creation
|
||||
2.2, 22-Jan-2001, update:
|
||||
- added Win32 support
|
||||
|
||||
.- */
|
||||
const ChfChar *ChfGetMessage( /* Retrieve a condition message */
|
||||
const int module_id,
|
||||
const int condition_code,
|
||||
const ChfChar *default_message
|
||||
)
|
||||
const ChfChar* ChfGetMessage( /* Retrieve a condition message */
|
||||
const int module_id, const int condition_code, const ChfChar* default_message )
|
||||
{
|
||||
const ChfChar *message;
|
||||
const ChfChar* message;
|
||||
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
if((message = chf_context.mrs_get(chf_context.mrs_data,
|
||||
module_id, condition_code, default_message)) == default_message &&
|
||||
module_id == CHF_ERRNO_SET)
|
||||
# ifdef _WIN32
|
||||
message = default_message;
|
||||
# else
|
||||
message = strerror(condition_code);
|
||||
# endif
|
||||
if ( ( message = chf_context.mrs_get( chf_context.mrs_data, module_id, condition_code, default_message ) ) == default_message &&
|
||||
module_id == CHF_ERRNO_SET )
|
||||
#ifdef _WIN32
|
||||
message = default_message;
|
||||
#else
|
||||
message = strerror( condition_code );
|
||||
#endif
|
||||
|
||||
return(message);
|
||||
return ( message );
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfBuildMessage
|
||||
|
@ -361,10 +339,10 @@ const ChfChar *ChfGetMessage( /* Retrieve a condition message */
|
|||
descriptor and returns a pointer to a string containing it.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_INIT
|
||||
if CHF hasn't been correctly initialized.
|
||||
if CHF hasn't been correctly initialized.
|
||||
|
||||
NOTE: The returned pointer points to per-thread static storage, which will be
|
||||
overwritten by subsequent calls to this function.
|
||||
overwritten by subsequent calls to this function.
|
||||
|
||||
WIN32:
|
||||
|
||||
|
@ -372,87 +350,81 @@ const ChfChar *ChfGetMessage( /* Retrieve a condition message */
|
|||
included in the message
|
||||
|
||||
.call :
|
||||
msg = ChfBuildMessage(descriptor);
|
||||
msg = ChfBuildMessage(descriptor);
|
||||
.input :
|
||||
const ChfDescriptor *descriptor, condition descriptor
|
||||
const ChfDescriptor *descriptor, condition descriptor
|
||||
.output :
|
||||
char *msg, pointer to the message associated with 'descriptor'
|
||||
char *msg, pointer to the message associated with 'descriptor'
|
||||
.status_codes :
|
||||
none
|
||||
none
|
||||
.notes :
|
||||
1.1, 16-May-1996, creation
|
||||
2.2, 22-Jan-2001, update:
|
||||
- added Win32 support
|
||||
|
||||
.- */
|
||||
ChfChar *ChfBuildMessage( /* Build a condition message */
|
||||
const ChfDescriptor *descriptor
|
||||
)
|
||||
ChfChar* ChfBuildMessage( /* Build a condition message */
|
||||
const ChfDescriptor* descriptor )
|
||||
{
|
||||
ChfChar *tmp_p;
|
||||
ChfChar *tmp_end;
|
||||
ChfChar def_message[CHF_DEF_MESSAGE_LENGTH];
|
||||
ChfSeverity severity;
|
||||
ChfChar* tmp_p;
|
||||
ChfChar* tmp_end;
|
||||
ChfChar def_message[ CHF_DEF_MESSAGE_LENGTH ];
|
||||
ChfSeverity severity;
|
||||
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
/* Set appropriate pointers to the start/end of the message buffer */
|
||||
tmp_p = chf_context.message_buffer;
|
||||
tmp_end = tmp_p + CHF_MAX_MESSAGE_LENGTH;
|
||||
/* Set appropriate pointers to the start/end of the message buffer */
|
||||
tmp_p = chf_context.message_buffer;
|
||||
tmp_end = tmp_p + CHF_MAX_MESSAGE_LENGTH;
|
||||
|
||||
#ifndef _WIN32
|
||||
/* The message starts with "<app_name>: " if the condition is the first of
|
||||
its condition group, with "\t" if not.
|
||||
*/
|
||||
if(descriptor == chf_context.condition_sp-1)
|
||||
{
|
||||
tmp_p = scopy(tmp_p, chf_context.app_name, tmp_end);
|
||||
tmp_p = scopy(tmp_p, separator, tmp_end);
|
||||
}
|
||||
/* The message starts with "<app_name>: " if the condition is the first of
|
||||
its condition group, with "\t" if not.
|
||||
*/
|
||||
if ( descriptor == chf_context.condition_sp - 1 ) {
|
||||
tmp_p = scopy( tmp_p, chf_context.app_name, tmp_end );
|
||||
tmp_p = scopy( tmp_p, separator, tmp_end );
|
||||
}
|
||||
|
||||
else
|
||||
tmp_p = scopy(tmp_p, ChfText("\t"), tmp_end);
|
||||
else
|
||||
tmp_p = scopy( tmp_p, ChfText( "\t" ), tmp_end );
|
||||
#endif
|
||||
|
||||
/* The message continues with the module name */
|
||||
ChfSprintf(def_message, CHF_DEF_MID_MSG_FMT, ChfGetModuleId(descriptor));
|
||||
/* The message continues with the module name */
|
||||
ChfSprintf( def_message, CHF_DEF_MID_MSG_FMT, ChfGetModuleId( descriptor ) );
|
||||
|
||||
tmp_p = scopy(tmp_p,
|
||||
ChfGetMessage(CHF_MODULE_NAMES_SET, ChfGetModuleId(descriptor),
|
||||
def_message), tmp_end);
|
||||
tmp_p = scopy( tmp_p, ChfGetMessage( CHF_MODULE_NAMES_SET, ChfGetModuleId( descriptor ), def_message ), tmp_end );
|
||||
|
||||
/* Add also the extended information, if any */
|
||||
if(ChfGetLineNumber(descriptor) != CHF_UNKNOWN_LINE_NUMBER)
|
||||
{
|
||||
tmp_p = scopy(tmp_p, ChfText(" "), tmp_end);
|
||||
/* Add also the extended information, if any */
|
||||
if ( ChfGetLineNumber( descriptor ) != CHF_UNKNOWN_LINE_NUMBER ) {
|
||||
tmp_p = scopy( tmp_p, ChfText( " " ), tmp_end );
|
||||
|
||||
ChfSprintf(def_message, CHF_EXTENDED_INFO_FMT,
|
||||
ChfGetFileName(descriptor), ChfGetLineNumber(descriptor));
|
||||
|
||||
tmp_p = scopy(tmp_p, def_message, tmp_end);
|
||||
}
|
||||
ChfSprintf( def_message, CHF_EXTENDED_INFO_FMT, ChfGetFileName( descriptor ), ChfGetLineNumber( descriptor ) );
|
||||
|
||||
tmp_p = scopy(tmp_p, separator, tmp_end);
|
||||
tmp_p = scopy( tmp_p, def_message, tmp_end );
|
||||
}
|
||||
|
||||
tmp_p = scopy( tmp_p, separator, tmp_end );
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Add the severity code of the message */
|
||||
tmp_p = scopy(tmp_p,
|
||||
((severity = ChfGetSeverity(descriptor)) < CHF_SUCCESS ||
|
||||
severity > CHF_FATAL) ? CHF_UNKNOWN_SEVERITY : severity_name[severity],
|
||||
tmp_end);
|
||||
/* Add the severity code of the message */
|
||||
tmp_p = scopy( tmp_p,
|
||||
( ( severity = ChfGetSeverity( descriptor ) ) < CHF_SUCCESS || severity > CHF_FATAL ) ? CHF_UNKNOWN_SEVERITY
|
||||
: severity_name[ severity ],
|
||||
tmp_end );
|
||||
|
||||
tmp_p = scopy(tmp_p, separator, tmp_end);
|
||||
tmp_p = scopy( tmp_p, separator, tmp_end );
|
||||
#endif
|
||||
|
||||
/* The message ends with the partial message from the descriptor */
|
||||
tmp_p = scopy(tmp_p, ChfGetPartialMessage(descriptor), tmp_end);
|
||||
(void)scopy(tmp_p, CHF_MESSAGE_TERMINATOR, tmp_end);
|
||||
/* The message ends with the partial message from the descriptor */
|
||||
tmp_p = scopy( tmp_p, ChfGetPartialMessage( descriptor ), tmp_end );
|
||||
( void )scopy( tmp_p, CHF_MESSAGE_TERMINATOR, tmp_end );
|
||||
|
||||
return chf_context.message_buffer;
|
||||
return chf_context.message_buffer;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfInit
|
||||
|
@ -467,29 +439,29 @@ ChfChar *ChfBuildMessage( /* Build a condition message */
|
|||
function.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_DUP_INIT
|
||||
if CHF has already been initialized before.
|
||||
if CHF has already been initialized before.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_PTHREAD
|
||||
if a pthread operation fails.
|
||||
if a pthread operation fails.
|
||||
|
||||
.call :
|
||||
cc = ChfInit(app_name, options,
|
||||
mrs_data, mrs_get, mrs_exit,
|
||||
condition_stack_size, handler_stack_size,
|
||||
exit_code);
|
||||
cc = ChfInit(app_name, options,
|
||||
mrs_data, mrs_get, mrs_exit,
|
||||
condition_stack_size, handler_stack_size,
|
||||
exit_code);
|
||||
.input :
|
||||
const char *app_name, Application's name
|
||||
const ChfOptions options, Options
|
||||
void *mrs_data, Message retrieval private data
|
||||
ChfMrsGet mrs_get, 'GetMessage' function
|
||||
ChfMrsExit mrs_exit, 'Exit' function
|
||||
const int condition_stack_size, Size of the condition stack
|
||||
const int handler_stack_size, Size of the handler stack
|
||||
const int exit_code, Abnormal exit code
|
||||
const char *app_name, Application's name
|
||||
const ChfOptions options, Options
|
||||
void *mrs_data, Message retrieval private data
|
||||
ChfMrsGet mrs_get, 'GetMessage' function
|
||||
ChfMrsExit mrs_exit, 'Exit' function
|
||||
const int condition_stack_size, Size of the condition stack
|
||||
const int handler_stack_size, Size of the handler stack
|
||||
const int exit_code, Abnormal exit code
|
||||
.output :
|
||||
int cc, condition code
|
||||
int cc, condition code
|
||||
.status_codes :
|
||||
CHF_F_MALLOC, FATAL, dynamic memory allocation failed
|
||||
CHF_F_MALLOC, FATAL, dynamic memory allocation failed
|
||||
.notes :
|
||||
1.1, 13-May-1996, creation
|
||||
1.6, 15-Jan-1997, update:
|
||||
|
@ -500,104 +472,98 @@ ChfChar *ChfBuildMessage( /* Build a condition message */
|
|||
- added Win32 support; a malloc() call was not portable.
|
||||
|
||||
.- */
|
||||
int ChfInit( /* Generic initialization */
|
||||
const ChfChar *app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
void *mrs_data, /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit, /* 'Exit' function */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
int ChfInit( /* Generic initialization */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
void* mrs_data, /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit, /* 'Exit' function */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
)
|
||||
{
|
||||
int cc;
|
||||
int cc;
|
||||
|
||||
/* Check that CHF has not been initialized yet */
|
||||
/* Check that CHF has not been initialized yet */
|
||||
#ifndef _REENTRANT
|
||||
if(_chf_context.state != CHF_UNKNOWN) ChfAbort(CHF_ABORT_DUP_INIT);
|
||||
if ( _chf_context.state != CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_DUP_INIT );
|
||||
#else
|
||||
/* Reentrant check; lock context_mutex first */
|
||||
if(pthread_mutex_lock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
||||
if(_chf_context.state != CHF_UNKNOWN)
|
||||
{
|
||||
if(pthread_mutex_unlock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
||||
ChfAbort(CHF_ABORT_DUP_INIT);
|
||||
}
|
||||
/* Reentrant check; lock context_mutex first */
|
||||
if ( pthread_mutex_lock( &context_mutex ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
if ( _chf_context.state != CHF_UNKNOWN ) {
|
||||
if ( pthread_mutex_unlock( &context_mutex ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
ChfAbort( CHF_ABORT_DUP_INIT );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _REENTRANT
|
||||
if((_chf_context.condition_stack =
|
||||
(ChfDescriptor *)
|
||||
malloc((size_t)(condition_stack_size+1)*sizeof(ChfDescriptor))) ==
|
||||
CHF_NULL_DESCRIPTOR)
|
||||
cc = CHF_F_MALLOC;
|
||||
if ( ( _chf_context.condition_stack = ( ChfDescriptor* )malloc( ( size_t )( condition_stack_size + 1 ) * sizeof( ChfDescriptor ) ) ) ==
|
||||
CHF_NULL_DESCRIPTOR )
|
||||
cc = CHF_F_MALLOC;
|
||||
|
||||
else if((_chf_context.handler_stack =
|
||||
(ChfHandlerDescriptor *)
|
||||
malloc((size_t)handler_stack_size*sizeof(ChfHandlerDescriptor))) ==
|
||||
(ChfHandlerDescriptor *)NULL)
|
||||
{
|
||||
free(_chf_context.condition_stack);
|
||||
cc = CHF_F_MALLOC;
|
||||
}
|
||||
else if ( ( _chf_context.handler_stack = ( ChfHandlerDescriptor* )malloc(
|
||||
( size_t )handler_stack_size * sizeof( ChfHandlerDescriptor ) ) ) == ( ChfHandlerDescriptor* )NULL ) {
|
||||
free( _chf_context.condition_stack );
|
||||
cc = CHF_F_MALLOC;
|
||||
}
|
||||
|
||||
else if((_chf_context.message_buffer =
|
||||
(ChfChar *)malloc(
|
||||
(size_t)(CHF_MAX_MESSAGE_LENGTH) * sizeof(ChfChar))) == (ChfChar *)NULL)
|
||||
{
|
||||
free(_chf_context.condition_stack);
|
||||
free(_chf_context.handler_stack);
|
||||
cc = CHF_F_MALLOC;
|
||||
}
|
||||
else if ( ( _chf_context.message_buffer = ( ChfChar* )malloc( ( size_t )( CHF_MAX_MESSAGE_LENGTH ) * sizeof( ChfChar ) ) ) ==
|
||||
( ChfChar* )NULL ) {
|
||||
free( _chf_context.condition_stack );
|
||||
free( _chf_context.handler_stack );
|
||||
cc = CHF_F_MALLOC;
|
||||
}
|
||||
|
||||
else
|
||||
else
|
||||
#else
|
||||
/* Reentrant init: condition_stack, handler_stack, message_buffer
|
||||
are not needed in the master Chf context.
|
||||
Init the Chf data key instead.
|
||||
*/
|
||||
_chf_context.condition_stack = CHF_NULL_DESCRIPTOR;
|
||||
_chf_context.handler_stack = (ChfHandlerDescriptor *)NULL;
|
||||
_chf_context.message_buffer = (char *)NULL;
|
||||
|
||||
if(pthread_key_create(&data_key, DestroyContext))
|
||||
ChfAbort(CHF_ABORT_PTHREAD);
|
||||
#endif
|
||||
|
||||
{
|
||||
/* Initialize the CHF context */
|
||||
_chf_context.app_name = app_name;
|
||||
_chf_context.options = options;
|
||||
_chf_context.mrs_data = mrs_data;
|
||||
_chf_context.mrs_get = mrs_get;
|
||||
_chf_context.mrs_exit = mrs_exit;
|
||||
_chf_context.condition_stack_size = condition_stack_size;
|
||||
_chf_context.handler_stack_size = handler_stack_size;
|
||||
_chf_context.exit_code = exit_code;
|
||||
_chf_context.condition_base = _chf_context.condition_sp =
|
||||
_chf_context.condition_stack;
|
||||
_chf_context.handler_sp = _chf_context.handler_stack;
|
||||
_chf_context.state = CHF_IDLE;
|
||||
|
||||
#ifndef _REENTRANT
|
||||
/* Push the default handler; in the reentrant case, this will be
|
||||
done once per thread, when the thread-specific context is primed.
|
||||
/* Reentrant init: condition_stack, handler_stack, message_buffer
|
||||
are not needed in the master Chf context.
|
||||
Init the Chf data key instead.
|
||||
*/
|
||||
ChfPushHandler(DefaultHandler, CHF_NULL_CONTEXT, CHF_NULL_POINTER);
|
||||
_chf_context.condition_stack = CHF_NULL_DESCRIPTOR;
|
||||
_chf_context.handler_stack = ( ChfHandlerDescriptor* )NULL;
|
||||
_chf_context.message_buffer = ( char* )NULL;
|
||||
|
||||
if ( pthread_key_create( &data_key, DestroyContext ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
#endif
|
||||
|
||||
cc = CHF_S_OK;
|
||||
}
|
||||
{
|
||||
/* Initialize the CHF context */
|
||||
_chf_context.app_name = app_name;
|
||||
_chf_context.options = options;
|
||||
_chf_context.mrs_data = mrs_data;
|
||||
_chf_context.mrs_get = mrs_get;
|
||||
_chf_context.mrs_exit = mrs_exit;
|
||||
_chf_context.condition_stack_size = condition_stack_size;
|
||||
_chf_context.handler_stack_size = handler_stack_size;
|
||||
_chf_context.exit_code = exit_code;
|
||||
_chf_context.condition_base = _chf_context.condition_sp = _chf_context.condition_stack;
|
||||
_chf_context.handler_sp = _chf_context.handler_stack;
|
||||
_chf_context.state = CHF_IDLE;
|
||||
|
||||
#ifndef _REENTRANT
|
||||
/* Push the default handler; in the reentrant case, this will be
|
||||
done once per thread, when the thread-specific context is primed.
|
||||
*/
|
||||
ChfPushHandler( DefaultHandler, CHF_NULL_CONTEXT, CHF_NULL_POINTER );
|
||||
#endif
|
||||
|
||||
cc = CHF_S_OK;
|
||||
}
|
||||
|
||||
#ifdef _REENTRANT
|
||||
if(pthread_mutex_unlock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
||||
if ( pthread_mutex_unlock( &context_mutex ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
#endif
|
||||
|
||||
return cc;
|
||||
return cc;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfExit
|
||||
|
@ -610,82 +576,82 @@ int ChfInit( /* Generic initialization */
|
|||
the application using ChfAbort() with abort code CHF_ABORT_INIT.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_INIT
|
||||
if CHF hasn't been initialized.
|
||||
if CHF hasn't been initialized.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_PTHREAD
|
||||
if a pthread operation fails.
|
||||
if a pthread operation fails.
|
||||
|
||||
.call :
|
||||
ChfExit();
|
||||
ChfExit();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
none
|
||||
none
|
||||
.notes :
|
||||
1.1, 24-May-1996, creation
|
||||
2.1, 19-May-2000, update:
|
||||
- added multithreading support
|
||||
|
||||
.- */
|
||||
void ChfExit(
|
||||
void
|
||||
)
|
||||
void ChfExit( void )
|
||||
{
|
||||
/* Check that CHF has been correctly initialized */
|
||||
/* Check that CHF has been correctly initialized */
|
||||
#ifndef _REENTRANT
|
||||
if(_chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
||||
if ( _chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
#else
|
||||
/* Reentrant check; lock context_mutex first */
|
||||
if(pthread_mutex_lock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
||||
if(_chf_context.state == CHF_UNKNOWN)
|
||||
{
|
||||
if(pthread_mutex_unlock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
||||
ChfAbort(CHF_ABORT_INIT);
|
||||
}
|
||||
/* Reentrant check; lock context_mutex first */
|
||||
if ( pthread_mutex_lock( &context_mutex ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
if ( _chf_context.state == CHF_UNKNOWN ) {
|
||||
if ( pthread_mutex_unlock( &context_mutex ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Destroy the context associated with this thread now; this is necessary
|
||||
to ensure that the context is actually destroyed when a single-threaded
|
||||
application links with the multithreaded version of Chf: in this case,
|
||||
pthread_exit() is called *after* ChfExit(), the Chf data key no longer
|
||||
exists when pthread_exit() is called and the destructor registered
|
||||
with pthread_key_create() does not take place.
|
||||
The data pointer associated with the Chf data key is set to NULL to
|
||||
avoid any subsequent reactivation of the destructor.
|
||||
*/
|
||||
/* Destroy the context associated with this thread now; this is necessary
|
||||
to ensure that the context is actually destroyed when a single-threaded
|
||||
application links with the multithreaded version of Chf: in this case,
|
||||
pthread_exit() is called *after* ChfExit(), the Chf data key no longer
|
||||
exists when pthread_exit() is called and the destructor registered
|
||||
with pthread_key_create() does not take place.
|
||||
The data pointer associated with the Chf data key is set to NULL to
|
||||
avoid any subsequent reactivation of the destructor.
|
||||
*/
|
||||
#ifdef _REENTRANT
|
||||
DestroyContext(&chf_context);
|
||||
if(pthread_setspecific(data_key, (void *)NULL))
|
||||
{
|
||||
(void)pthread_mutex_unlock(&context_mutex);
|
||||
ChfAbort(CHF_ABORT_PTHREAD);
|
||||
}
|
||||
DestroyContext( &chf_context );
|
||||
if ( pthread_setspecific( data_key, ( void* )NULL ) ) {
|
||||
( void )pthread_mutex_unlock( &context_mutex );
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Shut down the message retrieval subsystem first */
|
||||
_chf_context.mrs_exit(_chf_context.mrs_data);
|
||||
/* Shut down the message retrieval subsystem first */
|
||||
_chf_context.mrs_exit( _chf_context.mrs_data );
|
||||
|
||||
#ifndef _REENTRANT
|
||||
/* Free the dynamic memory previously allocated */
|
||||
free(_chf_context.message_buffer);
|
||||
free(_chf_context.handler_stack);
|
||||
free(_chf_context.condition_stack);
|
||||
/* Free the dynamic memory previously allocated */
|
||||
free( _chf_context.message_buffer );
|
||||
free( _chf_context.handler_stack );
|
||||
free( _chf_context.condition_stack );
|
||||
#else
|
||||
/* Destroy the Chf data key */
|
||||
if(pthread_key_delete(data_key)) ChfAbort(CHF_ABORT_PTHREAD);
|
||||
/* Destroy the Chf data key */
|
||||
if ( pthread_key_delete( data_key ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
#endif
|
||||
|
||||
/* Reset CHF state to prevent subsequent calls to ChfExit() itself */
|
||||
_chf_context.state = CHF_UNKNOWN;
|
||||
/* Reset CHF state to prevent subsequent calls to ChfExit() itself */
|
||||
_chf_context.state = CHF_UNKNOWN;
|
||||
|
||||
#ifdef _REENTRANT
|
||||
if(pthread_mutex_unlock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
||||
if ( pthread_mutex_unlock( &context_mutex ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : _ChfGetContext
|
||||
|
@ -701,80 +667,66 @@ void ChfExit(
|
|||
successful call to ChfInit().
|
||||
|
||||
.call :
|
||||
context = _ChfGetContext(void);
|
||||
context = _ChfGetContext(void);
|
||||
.input :
|
||||
.output :
|
||||
ChfContext *context, per-thread Chf context
|
||||
ChfContext *context, per-thread Chf context
|
||||
.status_codes :
|
||||
none
|
||||
none
|
||||
.notes :
|
||||
2.1, 19-May-2000, creation
|
||||
|
||||
.- */
|
||||
ChfContext *_ChfGetContext(
|
||||
void
|
||||
)
|
||||
ChfContext* _ChfGetContext( void )
|
||||
{
|
||||
ChfContext *context;
|
||||
ChfContext* context;
|
||||
|
||||
#ifndef _REENTRANT
|
||||
/* This function is doomed to fail if _REENTRANT is not defined */
|
||||
ChfAbort(CHF_ABORT_GET_CONTEXT);
|
||||
return((ChfContext *)NULL);
|
||||
/* This function is doomed to fail if _REENTRANT is not defined */
|
||||
ChfAbort( CHF_ABORT_GET_CONTEXT );
|
||||
return ( ( ChfContext* )NULL );
|
||||
#else
|
||||
/* Get the thread-specific context pointer associated with the
|
||||
CHF data key */
|
||||
if((context = (ChfContext *)pthread_getspecific(data_key))
|
||||
== (ChfContext *)NULL)
|
||||
{
|
||||
/* No context pointer; prime a new one, cloning the master context */
|
||||
if((context = (ChfContext *)malloc(sizeof(ChfContext)))
|
||||
== (ChfContext *)NULL)
|
||||
ChfAbort(CHF_ABORT_GET_CONTEXT);
|
||||
/* Get the thread-specific context pointer associated with the
|
||||
CHF data key */
|
||||
if ( ( context = ( ChfContext* )pthread_getspecific( data_key ) ) == ( ChfContext* )NULL ) {
|
||||
/* No context pointer; prime a new one, cloning the master context */
|
||||
if ( ( context = ( ChfContext* )malloc( sizeof( ChfContext ) ) ) == ( ChfContext* )NULL )
|
||||
ChfAbort( CHF_ABORT_GET_CONTEXT );
|
||||
|
||||
memcpy(context, &_chf_context, sizeof(ChfContext));
|
||||
memcpy( context, &_chf_context, sizeof( ChfContext ) );
|
||||
|
||||
/* Allocate per-thread stacks and message buffer */
|
||||
if((context->condition_stack =
|
||||
(ChfDescriptor *)
|
||||
malloc((size_t)(context->condition_stack_size+1)
|
||||
*sizeof(ChfDescriptor))) == CHF_NULL_DESCRIPTOR)
|
||||
ChfAbort(CHF_ABORT_GET_CONTEXT);
|
||||
/* Allocate per-thread stacks and message buffer */
|
||||
if ( ( context->condition_stack = ( ChfDescriptor* )malloc( ( size_t )( context->condition_stack_size + 1 ) *
|
||||
sizeof( ChfDescriptor ) ) ) == CHF_NULL_DESCRIPTOR )
|
||||
ChfAbort( CHF_ABORT_GET_CONTEXT );
|
||||
|
||||
if((context->handler_stack =
|
||||
(ChfHandlerDescriptor *)
|
||||
malloc((size_t)(context->handler_stack_size)
|
||||
*sizeof(ChfHandlerDescriptor))) == (ChfHandlerDescriptor *)NULL)
|
||||
{
|
||||
free(context->condition_stack);
|
||||
ChfAbort(CHF_ABORT_GET_CONTEXT);
|
||||
if ( ( context->handler_stack = ( ChfHandlerDescriptor* )malloc(
|
||||
( size_t )( context->handler_stack_size ) * sizeof( ChfHandlerDescriptor ) ) ) == ( ChfHandlerDescriptor* )NULL ) {
|
||||
free( context->condition_stack );
|
||||
ChfAbort( CHF_ABORT_GET_CONTEXT );
|
||||
}
|
||||
|
||||
if ( ( context->message_buffer = ( char* )malloc( ( size_t )( CHF_MAX_MESSAGE_LENGTH ) ) ) == ( char* )NULL ) {
|
||||
free( context->condition_stack );
|
||||
free( context->handler_stack );
|
||||
ChfAbort( CHF_ABORT_GET_CONTEXT );
|
||||
}
|
||||
|
||||
/* Initialize stack pointers */
|
||||
context->condition_base = context->condition_sp = context->condition_stack;
|
||||
context->handler_sp = context->handler_stack;
|
||||
|
||||
/* Set the thread-specific context pointer; this must be done
|
||||
before invoking any other function using the context,
|
||||
including ChfPushHandler() below.
|
||||
*/
|
||||
if ( pthread_setspecific( data_key, context ) )
|
||||
ChfAbort( CHF_ABORT_GET_CONTEXT );
|
||||
|
||||
/* Push the default handler */
|
||||
ChfPushHandler( DefaultHandler, CHF_NULL_CONTEXT, CHF_NULL_POINTER );
|
||||
}
|
||||
|
||||
if((context->message_buffer =
|
||||
(char *)
|
||||
malloc((size_t)(CHF_MAX_MESSAGE_LENGTH))) == (char *)NULL)
|
||||
{
|
||||
free(context->condition_stack);
|
||||
free(context->handler_stack);
|
||||
ChfAbort(CHF_ABORT_GET_CONTEXT);
|
||||
}
|
||||
|
||||
/* Initialize stack pointers */
|
||||
context->condition_base = context->condition_sp =
|
||||
context->condition_stack;
|
||||
context->handler_sp = context->handler_stack;
|
||||
|
||||
/* Set the thread-specific context pointer; this must be done
|
||||
before invoking any other function using the context,
|
||||
including ChfPushHandler() below.
|
||||
*/
|
||||
if(pthread_setspecific(data_key, context))
|
||||
ChfAbort(CHF_ABORT_GET_CONTEXT);
|
||||
|
||||
/* Push the default handler */
|
||||
ChfPushHandler(DefaultHandler, CHF_NULL_CONTEXT, CHF_NULL_POINTER);
|
||||
}
|
||||
|
||||
return context;
|
||||
return context;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -35,24 +35,23 @@ static char rcs_id[] = "$Id: chf_msgc.c,v 2.2 2001/01/25 14:06:47 cibrario Exp $
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#ifndef _WIN32
|
||||
#include <locale.h>
|
||||
#include <nl_types.h>
|
||||
# include <locale.h>
|
||||
# include <nl_types.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Global and static variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -62,41 +61,28 @@ static char rcs_id[] = "$Id: chf_msgc.c,v 2.2 2001/01/25 14:06:47 cibrario Exp $
|
|||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef _WIN32
|
||||
typedef struct
|
||||
{
|
||||
nl_catd catalog; /* Message catalog descriptor */
|
||||
}
|
||||
ChfMsgcatContext;
|
||||
typedef struct {
|
||||
nl_catd catalog; /* Message catalog descriptor */
|
||||
} ChfMsgcatContext;
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
static const char *GetMessage(
|
||||
void *private_context,
|
||||
const int module_id,
|
||||
const int condition_code,
|
||||
const char *default_message
|
||||
)
|
||||
static const char* GetMessage( void* private_context, const int module_id, const int condition_code, const char* default_message )
|
||||
{
|
||||
return(catgets(((ChfMsgcatContext *)private_context)->catalog, module_id,
|
||||
condition_code, default_message));
|
||||
return ( catgets( ( ( ChfMsgcatContext* )private_context )->catalog, module_id, condition_code, default_message ) );
|
||||
}
|
||||
|
||||
static void ExitMessage(
|
||||
void *private_context
|
||||
)
|
||||
static void ExitMessage( void* private_context )
|
||||
{
|
||||
(void)catclose(((ChfMsgcatContext *)private_context)->catalog);
|
||||
free(private_context);
|
||||
( void )catclose( ( ( ChfMsgcatContext* )private_context )->catalog );
|
||||
free( private_context );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Public functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -115,7 +101,7 @@ static void ExitMessage(
|
|||
other CHF initialization routines before using any other CHF function.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_DUP_INIT
|
||||
if CHF has already been initialized before.
|
||||
if CHF has already been initialized before.
|
||||
|
||||
WIN32:
|
||||
|
||||
|
@ -123,79 +109,72 @@ static void ExitMessage(
|
|||
always returns CHF_F_NOT_AVAILABLE
|
||||
|
||||
.call :
|
||||
cc = ChfMsgcatInit(app_name, options,
|
||||
msgcat_name,
|
||||
condition_stack_size, handler_stack_size,
|
||||
exit_code);
|
||||
cc = ChfMsgcatInit(app_name, options,
|
||||
msgcat_name,
|
||||
condition_stack_size, handler_stack_size,
|
||||
exit_code);
|
||||
.input :
|
||||
const char *app_name, Application's name
|
||||
const ChfOptions options, Options
|
||||
const char *msgcat_name, Name of the message catalog
|
||||
const int condition_stack_size, Size of the condition stack
|
||||
const int handler_stack_size, Size of the handler stack
|
||||
const int exit_code, Abnormal exit code
|
||||
const char *app_name, Application's name
|
||||
const ChfOptions options, Options
|
||||
const char *msgcat_name, Name of the message catalog
|
||||
const int condition_stack_size, Size of the condition stack
|
||||
const int handler_stack_size, Size of the handler stack
|
||||
const int exit_code, Abnormal exit code
|
||||
.output :
|
||||
int cc, condition code
|
||||
int cc, condition code
|
||||
.status_codes :
|
||||
CHF_F_SETLOCALE, setlocale() failed
|
||||
CHF_F_CATOPEN, catopen() failed
|
||||
CHF_F_MALLOC, FATAL, memory allocation failed
|
||||
CHF_F_NOT_AVAILABLE, FATAL, function not available
|
||||
CHF_F_SETLOCALE, setlocale() failed
|
||||
CHF_F_CATOPEN, catopen() failed
|
||||
CHF_F_MALLOC, FATAL, memory allocation failed
|
||||
CHF_F_NOT_AVAILABLE, FATAL, function not available
|
||||
.notes :
|
||||
1.1, 17-May-1996, creation
|
||||
2.2, 22-Jan-2001, update:
|
||||
- added Win32 support
|
||||
|
||||
.- */
|
||||
int ChfMsgcatInit( /* Initialization with msgcat subsystem */
|
||||
const ChfChar *app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfChar *msgcat_name, /* Name of the message catalog */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
int ChfMsgcatInit( /* Initialization with msgcat subsystem */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfChar* msgcat_name, /* Name of the message catalog */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* This function always fails in _WIN32, because message catalogs
|
||||
are not supported.
|
||||
*/
|
||||
return CHF_F_NOT_AVAILABLE;
|
||||
/* This function always fails in _WIN32, because message catalogs
|
||||
are not supported.
|
||||
*/
|
||||
return CHF_F_NOT_AVAILABLE;
|
||||
|
||||
#else
|
||||
ChfMsgcatContext *private_context;
|
||||
int cc;
|
||||
ChfMsgcatContext* private_context;
|
||||
int cc;
|
||||
|
||||
if((private_context =
|
||||
(ChfMsgcatContext *)malloc(sizeof(ChfMsgcatContext))) ==
|
||||
(ChfMsgcatContext *)NULL)
|
||||
cc = CHF_F_MALLOC;
|
||||
if ( ( private_context = ( ChfMsgcatContext* )malloc( sizeof( ChfMsgcatContext ) ) ) == ( ChfMsgcatContext* )NULL )
|
||||
cc = CHF_F_MALLOC;
|
||||
|
||||
else if(setlocale(LC_ALL, "") == (char *)NULL)
|
||||
{
|
||||
free(private_context);
|
||||
cc = CHF_F_SETLOCALE;
|
||||
}
|
||||
else if ( setlocale( LC_ALL, "" ) == ( char* )NULL ) {
|
||||
free( private_context );
|
||||
cc = CHF_F_SETLOCALE;
|
||||
}
|
||||
|
||||
else if((private_context->catalog = catopen(msgcat_name, 0)) ==
|
||||
(nl_catd)(-1))
|
||||
{
|
||||
free(private_context);
|
||||
cc = CHF_F_CATOPEN;
|
||||
}
|
||||
else if ( ( private_context->catalog = catopen( msgcat_name, 0 ) ) == ( nl_catd )( -1 ) ) {
|
||||
free( private_context );
|
||||
cc = CHF_F_CATOPEN;
|
||||
}
|
||||
|
||||
else if((cc = ChfInit(app_name, options, (void *)private_context,
|
||||
GetMessage, ExitMessage, condition_stack_size, handler_stack_size,
|
||||
exit_code)) != CHF_S_OK)
|
||||
{
|
||||
(void)catclose(private_context->catalog);
|
||||
free(private_context);
|
||||
}
|
||||
else if ( ( cc = ChfInit( app_name, options, ( void* )private_context, GetMessage, ExitMessage, condition_stack_size,
|
||||
handler_stack_size, exit_code ) ) != CHF_S_OK ) {
|
||||
( void )catclose( private_context->catalog );
|
||||
free( private_context );
|
||||
}
|
||||
|
||||
else
|
||||
cc = CHF_S_OK;
|
||||
else
|
||||
cc = CHF_S_OK;
|
||||
|
||||
return cc;
|
||||
return cc;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -44,19 +44,18 @@ static char rcs_id[] = "$Id: chf_sig.c,v 2.2 2001/01/25 14:07:42 cibrario Exp $"
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <setjmp.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfSignal
|
||||
|
@ -68,26 +67,26 @@ static char rcs_id[] = "$Id: chf_sig.c,v 2.2 2001/01/25 14:07:42 cibrario Exp $"
|
|||
handlers.
|
||||
|
||||
NOTE: This function uses the CHF function 'ChfAbort()' to
|
||||
abort the application if either
|
||||
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
||||
- the last handler on the handler stack has returned an invalid action
|
||||
code (abort code CHF_ABORT_INVALID_ACTION)
|
||||
- one of the handlers has requested the CHF_UNWIND action while
|
||||
CHF was already unwinding (abort code CHF_ABORT_ALREADY_UNWINDING)
|
||||
- a CHF_FATAL condition was signalled while CHF was unwinding
|
||||
(abort code CHF_ABORT_FATAL_UNWINDING)
|
||||
- all the handlers refused to handle a condition (abort code
|
||||
CHF_ABORT_IMPROPERLY_HANDLED)
|
||||
abort the application if either
|
||||
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
||||
- the last handler on the handler stack has returned an invalid action
|
||||
code (abort code CHF_ABORT_INVALID_ACTION)
|
||||
- one of the handlers has requested the CHF_UNWIND action while
|
||||
CHF was already unwinding (abort code CHF_ABORT_ALREADY_UNWINDING)
|
||||
- a CHF_FATAL condition was signalled while CHF was unwinding
|
||||
(abort code CHF_ABORT_FATAL_UNWINDING)
|
||||
- all the handlers refused to handle a condition (abort code
|
||||
CHF_ABORT_IMPROPERLY_HANDLED)
|
||||
|
||||
.call :
|
||||
ChfSignal();
|
||||
ChfSignal();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
(*) CHF_F_COND_STACK_FULL, the condition stack is full
|
||||
(*) CHF_F_INVALID_ACTION, invalid handler action (%d)
|
||||
(*) CHF_F_COND_STACK_FULL, the condition stack is full
|
||||
(*) CHF_F_INVALID_ACTION, invalid handler action (%d)
|
||||
.notes :
|
||||
1.1, 10-May-1996, creation
|
||||
1.6, 15-Jan-1997, update & bug fix:
|
||||
|
@ -99,269 +98,246 @@ static char rcs_id[] = "$Id: chf_sig.c,v 2.2 2001/01/25 14:07:42 cibrario Exp $"
|
|||
- added support for structured condition handling
|
||||
|
||||
.- */
|
||||
void ChfSignal(
|
||||
void
|
||||
)
|
||||
void ChfSignal( void )
|
||||
{
|
||||
ChfState saved_state;
|
||||
ChfDescriptor *saved_condition_base;
|
||||
ChfDescriptor *current_condition;
|
||||
ChfHandlerDescriptor *saved_handler_sp;
|
||||
ChfHandlerDescriptor *handler_up;
|
||||
ChfHandlerDescriptor *unwind_handler;
|
||||
ChfAction handler_result;
|
||||
ChfState saved_state;
|
||||
ChfDescriptor* saved_condition_base;
|
||||
ChfDescriptor* current_condition;
|
||||
ChfHandlerDescriptor* saved_handler_sp;
|
||||
ChfHandlerDescriptor* handler_up;
|
||||
ChfHandlerDescriptor* unwind_handler;
|
||||
ChfAction handler_result;
|
||||
|
||||
/* Check that CHF has been correctly initialized and save the current CHF
|
||||
state. If CHF was CHF_IDLE change state to CHF_SIGNALING, else if CHF was
|
||||
CHF_UNWINDING change to CHF_SIGNAL_UNWINDING, otherwise remain in the
|
||||
previous state (that must be CHF_SIGNALING)
|
||||
*/
|
||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
||||
saved_state = chf_context.state;
|
||||
|
||||
if(chf_context.state == CHF_IDLE)
|
||||
chf_context.state = CHF_SIGNALING;
|
||||
else if(chf_context.state == CHF_UNWINDING)
|
||||
chf_context.state = CHF_SIGNAL_UNWINDING;
|
||||
|
||||
if(chf_context.condition_sp > chf_context.condition_base)
|
||||
{
|
||||
/* Save the base of the current condition group and then update it in
|
||||
order to allow further generation of conditions inside the condition
|
||||
handlers that will be called soon.
|
||||
/* Check that CHF has been correctly initialized and save the current CHF
|
||||
state. If CHF was CHF_IDLE change state to CHF_SIGNALING, else if CHF was
|
||||
CHF_UNWINDING change to CHF_SIGNAL_UNWINDING, otherwise remain in the
|
||||
previous state (that must be CHF_SIGNALING)
|
||||
*/
|
||||
current_condition = chf_context.condition_sp-1;
|
||||
saved_condition_base = chf_context.condition_base;
|
||||
chf_context.condition_base = chf_context.condition_sp;
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
saved_state = chf_context.state;
|
||||
|
||||
/* Save the current condition handler pointer */
|
||||
saved_handler_sp = chf_context.handler_sp;
|
||||
if ( chf_context.state == CHF_IDLE )
|
||||
chf_context.state = CHF_SIGNALING;
|
||||
else if ( chf_context.state == CHF_UNWINDING )
|
||||
chf_context.state = CHF_SIGNAL_UNWINDING;
|
||||
|
||||
/* Call the condition handlers; the loop will exit either:
|
||||
- when the handler stack is empty, or
|
||||
- when the current handler returns either CHF_CONTINUE or CHF_UNWIND
|
||||
*/
|
||||
handler_result = CHF_RESIGNAL;
|
||||
while(handler_result == CHF_RESIGNAL &&
|
||||
chf_context.handler_sp > chf_context.handler_stack)
|
||||
{
|
||||
chf_context.handler_sp--;
|
||||
if ( chf_context.condition_sp > chf_context.condition_base ) {
|
||||
/* Save the base of the current condition group and then update it in
|
||||
order to allow further generation of conditions inside the condition
|
||||
handlers that will be called soon.
|
||||
*/
|
||||
current_condition = chf_context.condition_sp - 1;
|
||||
saved_condition_base = chf_context.condition_base;
|
||||
chf_context.condition_base = chf_context.condition_sp;
|
||||
|
||||
/* The current condition handler, described by chf_context.handler_sp,
|
||||
can recursively invoke ChfGenerate() and ChfSignal().
|
||||
|
||||
ChfGenerate() will store the new condition group starting from
|
||||
chf_context.condition_sp, that points to the first free slot
|
||||
of the condition stack. During the first generation, since
|
||||
chf_context.condition_sp == chf_context.condition_base, the
|
||||
link pointer of the condition will be NULL and, therefore,
|
||||
the condition will be the first of a new condition group.
|
||||
/* Save the current condition handler pointer */
|
||||
saved_handler_sp = chf_context.handler_sp;
|
||||
|
||||
ChfSignal() will signal the condition group described by the
|
||||
stack block from chf_context.condition_base to
|
||||
chf_context.condition_sp-1, if it contains at least one condition;
|
||||
it will call the handlers starting from chf_context.handler_sp-1,
|
||||
that describes the handler immediately preceding the current handler.
|
||||
*/
|
||||
handler_result = chf_context.handler_sp->handler(
|
||||
current_condition, chf_context.state,
|
||||
chf_context.handler_sp->handler_context);
|
||||
/* Call the condition handlers; the loop will exit either:
|
||||
- when the handler stack is empty, or
|
||||
- when the current handler returns either CHF_CONTINUE or CHF_UNWIND
|
||||
*/
|
||||
handler_result = CHF_RESIGNAL;
|
||||
while ( handler_result == CHF_RESIGNAL && chf_context.handler_sp > chf_context.handler_stack ) {
|
||||
chf_context.handler_sp--;
|
||||
|
||||
/* When the CHF state is CHF_SIGNALING, any condition group generated
|
||||
but not yet signalled when the current handler exits must be merged
|
||||
with the condition group currently being signalled, in order to allow
|
||||
the condition handlers to add their own conditions to the condition
|
||||
group. If the severity of the previous condition group was CHF_FATAL,
|
||||
the severity of the new group is forced to CHF_FATAL, too.
|
||||
|
||||
When the CHF state is CHF_UNWINDING, the condition group for
|
||||
which the UNWIND has been requested is 'frozen', no further
|
||||
modifications are allowed on it, and the condition group is simply
|
||||
discarded.
|
||||
*/
|
||||
if(chf_context.condition_sp > chf_context.condition_base)
|
||||
{
|
||||
if(chf_context.state == CHF_SIGNALING)
|
||||
{
|
||||
/* Force the new severity to CHF_FATAL if necessary */
|
||||
if(ChfGetSeverity(current_condition) == CHF_FATAL)
|
||||
ChfGetSeverity(chf_context.condition_sp-1) = CHF_FATAL;
|
||||
|
||||
/* Link together the condition groups */
|
||||
chf_context.condition_base->next = current_condition;
|
||||
current_condition = chf_context.condition_sp-1;
|
||||
chf_context.condition_base = chf_context.condition_sp;
|
||||
}
|
||||
|
||||
else
|
||||
chf_context.condition_sp = chf_context.condition_base;
|
||||
}
|
||||
|
||||
/* The action CHF_CONTINUE is not allowed if the current condition
|
||||
severity is CHF_FATAL; it's automatically changed to CHF_RESIGNAL
|
||||
*/
|
||||
if(handler_result == CHF_CONTINUE &&
|
||||
ChfGetSeverity(current_condition) == CHF_FATAL)
|
||||
handler_result = CHF_RESIGNAL;
|
||||
}
|
||||
|
||||
/* Perform the action requested by the last condition handler invoked */
|
||||
switch(handler_result)
|
||||
{
|
||||
case CHF_CONTINUE:
|
||||
{
|
||||
/* Restore the handler stack pointer; the next ChfSignal() invoked
|
||||
from our same nesting level will invoke our same handler chain
|
||||
again.
|
||||
*/
|
||||
chf_context.handler_sp = saved_handler_sp;
|
||||
|
||||
/* Discard the current condition group */
|
||||
chf_context.condition_base = chf_context.condition_sp =
|
||||
saved_condition_base;
|
||||
|
||||
/* Restore che saved CHF state */
|
||||
chf_context.state = saved_state;
|
||||
|
||||
/* Continue from the instruction following the ChfSignal() */
|
||||
break;
|
||||
}
|
||||
|
||||
case CHF_UNWIND:
|
||||
case CHF_UNWIND_KEEP:
|
||||
{
|
||||
/* Unwind the execution stack. Check that another unwind isn't
|
||||
already in progress
|
||||
*/
|
||||
if(chf_context.state == CHF_UNWINDING)
|
||||
ChfAbort(CHF_ABORT_ALREADY_UNWINDING);
|
||||
|
||||
else
|
||||
{
|
||||
/* Change CHF state */
|
||||
chf_context.state = CHF_UNWINDING;
|
||||
|
||||
/* chf_context.handler_sp points to the condition handler that
|
||||
has requested the unwind; call all the handlers again, starting
|
||||
from saved_handler_sp (top of the handler stack) up to and
|
||||
including chf_context.handler_sp.
|
||||
*/
|
||||
handler_up = saved_handler_sp;
|
||||
|
||||
while(handler_up > chf_context.handler_sp)
|
||||
{
|
||||
ChfAction unw_handler_result;
|
||||
handler_up--;
|
||||
|
||||
/* The current condition handler, described by handler_up
|
||||
/* The current condition handler, described by chf_context.handler_sp,
|
||||
can recursively invoke ChfGenerate() and ChfSignal().
|
||||
|
||||
ChfGenerate() will store the new condition group starting from
|
||||
chf_context.condition_sp, that points to the first free slot
|
||||
of the condition stack. During the first generation, since
|
||||
chf_context.condition_sp == chf_context.condition_base, the
|
||||
link pointer of the condition will be NULL and, therefore,
|
||||
the condition will be the first of a new condition group.
|
||||
|
||||
ChfSignal() will generate the condition group described by the
|
||||
stack block from chf_context.condition_base to
|
||||
chf_context.condition_sp-1, if it contains at least one
|
||||
condition; it will call the handlers starting from
|
||||
chf_context.handler_sp-1, that describes the handler
|
||||
immediately preceding the handler that has requested the unwind.
|
||||
ChfGenerate() will store the new condition group starting from
|
||||
chf_context.condition_sp, that points to the first free slot
|
||||
of the condition stack. During the first generation, since
|
||||
chf_context.condition_sp == chf_context.condition_base, the
|
||||
link pointer of the condition will be NULL and, therefore,
|
||||
the condition will be the first of a new condition group.
|
||||
|
||||
Further unwind requests are not allowed, and will trigger
|
||||
the condition CHF_F_UNWINDING
|
||||
ChfSignal() will signal the condition group described by the
|
||||
stack block from chf_context.condition_base to
|
||||
chf_context.condition_sp-1, if it contains at least one condition;
|
||||
it will call the handlers starting from chf_context.handler_sp-1,
|
||||
that describes the handler immediately preceding the current handler.
|
||||
*/
|
||||
unw_handler_result = handler_up->handler(
|
||||
current_condition, chf_context.state,
|
||||
handler_up->handler_context);
|
||||
handler_result =
|
||||
chf_context.handler_sp->handler( current_condition, chf_context.state, chf_context.handler_sp->handler_context );
|
||||
|
||||
/* When the CHF state is CHF_UNWINDING, any condition group
|
||||
generated but not yet signalled when the current handler
|
||||
returns must be discarded
|
||||
*/
|
||||
chf_context.condition_sp = chf_context.condition_base;
|
||||
}
|
||||
/* When the CHF state is CHF_SIGNALING, any condition group generated
|
||||
but not yet signalled when the current handler exits must be merged
|
||||
with the condition group currently being signalled, in order to allow
|
||||
the condition handlers to add their own conditions to the condition
|
||||
group. If the severity of the previous condition group was CHF_FATAL,
|
||||
the severity of the new group is forced to CHF_FATAL, too.
|
||||
|
||||
/* Restore the handler stack pointer, discarding the unwinded
|
||||
condition handlers. chf_context.handler_sp points to the
|
||||
handler that requested the unwind; that handler has been
|
||||
unwinded and its location is now the first free slot in the
|
||||
condition handler stack.
|
||||
*/
|
||||
unwind_handler = chf_context.handler_sp;
|
||||
When the CHF state is CHF_UNWINDING, the condition group for
|
||||
which the UNWIND has been requested is 'frozen', no further
|
||||
modifications are allowed on it, and the condition group is simply
|
||||
discarded.
|
||||
*/
|
||||
if ( chf_context.condition_sp > chf_context.condition_base ) {
|
||||
if ( chf_context.state == CHF_SIGNALING ) {
|
||||
/* Force the new severity to CHF_FATAL if necessary */
|
||||
if ( ChfGetSeverity( current_condition ) == CHF_FATAL )
|
||||
ChfGetSeverity( chf_context.condition_sp - 1 ) = CHF_FATAL;
|
||||
|
||||
if(handler_result == CHF_UNWIND)
|
||||
{
|
||||
/* Normal unwind:
|
||||
restore the condition stack pointers, discarding all condition
|
||||
groups.
|
||||
*/
|
||||
chf_context.condition_base = chf_context.condition_sp =
|
||||
chf_context.condition_stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Special unwind for structured condition handling:
|
||||
restore the condition_base pointer only, to keep the
|
||||
topmost condition group on the condition stack. This way,
|
||||
the condition group remains accessible after the unwind.
|
||||
*/
|
||||
chf_context.condition_base = saved_condition_base;
|
||||
}
|
||||
/* Link together the condition groups */
|
||||
chf_context.condition_base->next = current_condition;
|
||||
current_condition = chf_context.condition_sp - 1;
|
||||
chf_context.condition_base = chf_context.condition_sp;
|
||||
}
|
||||
|
||||
/* Change the CHF state to CHF_IDLE, and execute longjmp().
|
||||
If the handler hasn't a valid unwind_context associated with it,
|
||||
simply abort the application.
|
||||
*/
|
||||
chf_context.state = CHF_IDLE;
|
||||
else
|
||||
chf_context.condition_sp = chf_context.condition_base;
|
||||
}
|
||||
|
||||
if(unwind_handler->unwind_context == CHF_NULL_CONTEXT)
|
||||
ChfAbort(CHF_ABORT_SILENT);
|
||||
else
|
||||
ChfSiglongjmp(unwind_handler->unwind_context, 1);
|
||||
}
|
||||
/* The action CHF_CONTINUE is not allowed if the current condition
|
||||
severity is CHF_FATAL; it's automatically changed to CHF_RESIGNAL
|
||||
*/
|
||||
if ( handler_result == CHF_CONTINUE && ChfGetSeverity( current_condition ) == CHF_FATAL )
|
||||
handler_result = CHF_RESIGNAL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
/* Perform the action requested by the last condition handler invoked */
|
||||
switch ( handler_result ) {
|
||||
case CHF_CONTINUE:
|
||||
{
|
||||
/* Restore the handler stack pointer; the next ChfSignal() invoked
|
||||
from our same nesting level will invoke our same handler chain
|
||||
again.
|
||||
*/
|
||||
chf_context.handler_sp = saved_handler_sp;
|
||||
|
||||
case CHF_RESIGNAL:
|
||||
{
|
||||
ChfAbort(
|
||||
(chf_context.state == CHF_SIGNALING) ?
|
||||
CHF_ABORT_IMPROPERLY_HANDLED : CHF_ABORT_FATAL_UNWINDING);
|
||||
|
||||
break;
|
||||
}
|
||||
/* Discard the current condition group */
|
||||
chf_context.condition_base = chf_context.condition_sp = saved_condition_base;
|
||||
|
||||
default:
|
||||
{
|
||||
/* Invalid handler action detected; generate and immediately signal a
|
||||
condition if the broken handler isn't the last handler on the stack,
|
||||
otherwise call ChfAbort()
|
||||
*/
|
||||
if(chf_context.handler_sp > chf_context.handler_stack)
|
||||
{
|
||||
ChfCondition CHF_F_INVALID_ACTION, CHF_FATAL, handler_result
|
||||
ChfEnd;
|
||||
/* Restore che saved CHF state */
|
||||
chf_context.state = saved_state;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
/* Continue from the instruction following the ChfSignal() */
|
||||
break;
|
||||
}
|
||||
|
||||
else
|
||||
ChfAbort(CHF_ABORT_INVALID_ACTION);
|
||||
case CHF_UNWIND:
|
||||
case CHF_UNWIND_KEEP:
|
||||
{
|
||||
/* Unwind the execution stack. Check that another unwind isn't
|
||||
already in progress
|
||||
*/
|
||||
if ( chf_context.state == CHF_UNWINDING )
|
||||
ChfAbort( CHF_ABORT_ALREADY_UNWINDING );
|
||||
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* Change CHF state */
|
||||
chf_context.state = CHF_UNWINDING;
|
||||
|
||||
/* chf_context.handler_sp points to the condition handler that
|
||||
has requested the unwind; call all the handlers again, starting
|
||||
from saved_handler_sp (top of the handler stack) up to and
|
||||
including chf_context.handler_sp.
|
||||
*/
|
||||
handler_up = saved_handler_sp;
|
||||
|
||||
while ( handler_up > chf_context.handler_sp ) {
|
||||
ChfAction unw_handler_result;
|
||||
handler_up--;
|
||||
|
||||
/* The current condition handler, described by handler_up
|
||||
can recursively invoke ChfGenerate() and ChfSignal().
|
||||
|
||||
ChfGenerate() will store the new condition group starting from
|
||||
chf_context.condition_sp, that points to the first free slot
|
||||
of the condition stack. During the first generation, since
|
||||
chf_context.condition_sp == chf_context.condition_base, the
|
||||
link pointer of the condition will be NULL and, therefore,
|
||||
the condition will be the first of a new condition group.
|
||||
|
||||
ChfSignal() will generate the condition group described by the
|
||||
stack block from chf_context.condition_base to
|
||||
chf_context.condition_sp-1, if it contains at least one
|
||||
condition; it will call the handlers starting from
|
||||
chf_context.handler_sp-1, that describes the handler
|
||||
immediately preceding the handler that has requested the unwind.
|
||||
|
||||
Further unwind requests are not allowed, and will trigger
|
||||
the condition CHF_F_UNWINDING
|
||||
*/
|
||||
unw_handler_result = handler_up->handler( current_condition, chf_context.state, handler_up->handler_context );
|
||||
|
||||
/* When the CHF state is CHF_UNWINDING, any condition group
|
||||
generated but not yet signalled when the current handler
|
||||
returns must be discarded
|
||||
*/
|
||||
chf_context.condition_sp = chf_context.condition_base;
|
||||
}
|
||||
|
||||
/* Restore the handler stack pointer, discarding the unwinded
|
||||
condition handlers. chf_context.handler_sp points to the
|
||||
handler that requested the unwind; that handler has been
|
||||
unwinded and its location is now the first free slot in the
|
||||
condition handler stack.
|
||||
*/
|
||||
unwind_handler = chf_context.handler_sp;
|
||||
|
||||
if ( handler_result == CHF_UNWIND ) {
|
||||
/* Normal unwind:
|
||||
restore the condition stack pointers, discarding all condition
|
||||
groups.
|
||||
*/
|
||||
chf_context.condition_base = chf_context.condition_sp = chf_context.condition_stack;
|
||||
} else {
|
||||
/* Special unwind for structured condition handling:
|
||||
restore the condition_base pointer only, to keep the
|
||||
topmost condition group on the condition stack. This way,
|
||||
the condition group remains accessible after the unwind.
|
||||
*/
|
||||
chf_context.condition_base = saved_condition_base;
|
||||
}
|
||||
|
||||
/* Change the CHF state to CHF_IDLE, and execute longjmp().
|
||||
If the handler hasn't a valid unwind_context associated with it,
|
||||
simply abort the application.
|
||||
*/
|
||||
chf_context.state = CHF_IDLE;
|
||||
|
||||
if ( unwind_handler->unwind_context == CHF_NULL_CONTEXT )
|
||||
ChfAbort( CHF_ABORT_SILENT );
|
||||
else
|
||||
ChfSiglongjmp( unwind_handler->unwind_context, 1 );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CHF_RESIGNAL:
|
||||
{
|
||||
ChfAbort( ( chf_context.state == CHF_SIGNALING ) ? CHF_ABORT_IMPROPERLY_HANDLED : CHF_ABORT_FATAL_UNWINDING );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
/* Invalid handler action detected; generate and immediately signal a
|
||||
condition if the broken handler isn't the last handler on the stack,
|
||||
otherwise call ChfAbort()
|
||||
*/
|
||||
if ( chf_context.handler_sp > chf_context.handler_stack ) {
|
||||
ChfCondition CHF_F_INVALID_ACTION, CHF_FATAL, handler_result ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else
|
||||
ChfAbort( CHF_ABORT_INVALID_ACTION );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the old CHF state */
|
||||
chf_context.state = saved_state;
|
||||
/* Restore the old CHF state */
|
||||
chf_context.state = saved_state;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfDiscard
|
||||
|
@ -373,30 +349,30 @@ void ChfSignal(
|
|||
the condition stack is empty.
|
||||
|
||||
NOTE: This function uses the CHF function 'ChfAbort()' to
|
||||
abort the application if either
|
||||
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
||||
abort the application if either
|
||||
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
||||
|
||||
.call :
|
||||
ChfDiscard();
|
||||
ChfDiscard();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
none
|
||||
none
|
||||
.notes :
|
||||
1.1, 17-May-1996, creation
|
||||
|
||||
.- */
|
||||
void ChfDiscard( /* Discard the current conditions */
|
||||
void
|
||||
)
|
||||
void ChfDiscard( /* Discard the current conditions */
|
||||
void )
|
||||
{
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
/* Reset the current condition stack pointer to the current condition
|
||||
stack base pointer
|
||||
*/
|
||||
chf_context.condition_sp = chf_context.condition_base;
|
||||
/* Reset the current condition stack pointer to the current condition
|
||||
stack base pointer
|
||||
*/
|
||||
chf_context.condition_sp = chf_context.condition_base;
|
||||
}
|
||||
|
|
|
@ -31,20 +31,19 @@ static char rcs_id[] = "$Id: chf_st.c,v 2.2 2001/01/25 14:08:45 cibrario Exp $";
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Global and static variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -53,13 +52,10 @@ static char rcs_id[] = "$Id: chf_st.c,v 2.2 2001/01/25 14:08:45 cibrario Exp $";
|
|||
Private type definitions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const ChfTable *table;
|
||||
size_t size;
|
||||
}
|
||||
ChfStaticContext;
|
||||
|
||||
typedef struct {
|
||||
const ChfTable* table;
|
||||
size_t size;
|
||||
} ChfStaticContext;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private functions
|
||||
|
@ -69,88 +65,67 @@ typedef struct
|
|||
/* Win32 does not have bsearch();
|
||||
provide a simple one from glibc here.
|
||||
*/
|
||||
static void *bsearch(
|
||||
const void *key,
|
||||
const void *base,
|
||||
size_t nmemb,
|
||||
size_t size,
|
||||
int (*compar)(const void *, const void *)
|
||||
)
|
||||
static void* bsearch( const void* key, const void* base, size_t nmemb, size_t size, int ( *compar )( const void*, const void* ) )
|
||||
{
|
||||
size_t l, u, idx;
|
||||
const void *p;
|
||||
int comparison;
|
||||
size_t l, u, idx;
|
||||
const void* p;
|
||||
int comparison;
|
||||
|
||||
l = 0;
|
||||
u = nmemb;
|
||||
while (l < u)
|
||||
{
|
||||
idx = (l + u) / 2;
|
||||
p = (void *) (((const char *) base) + (idx * size));
|
||||
comparison = (*compar) (key, p);
|
||||
if (comparison < 0)
|
||||
u = idx;
|
||||
else if (comparison > 0)
|
||||
l = idx + 1;
|
||||
else
|
||||
return (void *) p;
|
||||
l = 0;
|
||||
u = nmemb;
|
||||
while ( l < u ) {
|
||||
idx = ( l + u ) / 2;
|
||||
p = ( void* )( ( ( const char* )base ) + ( idx * size ) );
|
||||
comparison = ( *compar )( key, p );
|
||||
if ( comparison < 0 )
|
||||
u = idx;
|
||||
else if ( comparison > 0 )
|
||||
l = idx + 1;
|
||||
else
|
||||
return ( void* )p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define GT 1
|
||||
#define LT -1
|
||||
#define EQ 0
|
||||
#define GT 1
|
||||
#define LT -1
|
||||
#define EQ 0
|
||||
|
||||
static int Search(
|
||||
const void *l,
|
||||
const void *r
|
||||
)
|
||||
static int Search( const void* l, const void* r )
|
||||
{
|
||||
if(((ChfTable *)l)->module > ((ChfTable *)r)->module)
|
||||
return(GT);
|
||||
if ( ( ( ChfTable* )l )->module > ( ( ChfTable* )r )->module )
|
||||
return ( GT );
|
||||
|
||||
else if(((ChfTable *)l)->module < ((ChfTable *)r)->module)
|
||||
return(LT);
|
||||
else if ( ( ( ChfTable* )l )->module < ( ( ChfTable* )r )->module )
|
||||
return ( LT );
|
||||
|
||||
else if(((ChfTable *)l)->code > ((ChfTable *)r)->code)
|
||||
return(GT);
|
||||
else if ( ( ( ChfTable* )l )->code > ( ( ChfTable* )r )->code )
|
||||
return ( GT );
|
||||
|
||||
else if(((ChfTable *)l)->code < ((ChfTable *)r)->code)
|
||||
return(LT);
|
||||
else if ( ( ( ChfTable* )l )->code < ( ( ChfTable* )r )->code )
|
||||
return ( LT );
|
||||
|
||||
return(EQ);
|
||||
return ( EQ );
|
||||
}
|
||||
|
||||
static const ChfChar *StGetMessage(
|
||||
void *private_context,
|
||||
const int module_id,
|
||||
const int condition_code,
|
||||
const ChfChar *default_message
|
||||
)
|
||||
static const ChfChar* StGetMessage( void* private_context, const int module_id, const int condition_code, const ChfChar* default_message )
|
||||
{
|
||||
ChfTable key;
|
||||
ChfTable *res;
|
||||
ChfTable key;
|
||||
ChfTable* res;
|
||||
|
||||
key.module = module_id;
|
||||
key.code = condition_code;
|
||||
key.module = module_id;
|
||||
key.code = condition_code;
|
||||
|
||||
if((res = bsearch(&key, ((ChfStaticContext *)private_context)->table,
|
||||
((ChfStaticContext *)private_context)->size, sizeof(ChfTable), Search)) ==
|
||||
(void *)NULL)
|
||||
return(default_message);
|
||||
if ( ( res = bsearch( &key, ( ( ChfStaticContext* )private_context )->table, ( ( ChfStaticContext* )private_context )->size,
|
||||
sizeof( ChfTable ), Search ) ) == ( void* )NULL )
|
||||
return ( default_message );
|
||||
|
||||
return(((ChfTable *)res)->msg_template);
|
||||
}
|
||||
|
||||
static void ExitMessage(
|
||||
void *private_context
|
||||
)
|
||||
{
|
||||
return ( ( ( ChfTable* )res )->msg_template );
|
||||
}
|
||||
|
||||
static void ExitMessage( void* private_context ) {}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Public functions
|
||||
|
@ -170,58 +145,54 @@ static void ExitMessage(
|
|||
other CHF initialization routines before using any other CHF function.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_DUP_INIT
|
||||
if CHF has already been initialized before.
|
||||
if CHF has already been initialized before.
|
||||
|
||||
.call :
|
||||
cc = ChfStaticInit(app_name, options,
|
||||
table, table_size,
|
||||
condition_stack_size, handler_stack_size,
|
||||
exit_code);
|
||||
cc = ChfStaticInit(app_name, options,
|
||||
table, table_size,
|
||||
condition_stack_size, handler_stack_size,
|
||||
exit_code);
|
||||
.input :
|
||||
const char *app_name, Application's name
|
||||
const ChfOptions options, Options
|
||||
const ChfTable *table, pointer to the static message table
|
||||
const size_t table_size, size of the table (# of entries)
|
||||
const int condition_stack_size, Size of the condition stack
|
||||
const int handler_stack_size, Size of the handler stack
|
||||
const int exit_code, Abnormal exit code
|
||||
const char *app_name, Application's name
|
||||
const ChfOptions options, Options
|
||||
const ChfTable *table, pointer to the static message table
|
||||
const size_t table_size, size of the table (# of entries)
|
||||
const int condition_stack_size, Size of the condition stack
|
||||
const int handler_stack_size, Size of the handler stack
|
||||
const int exit_code, Abnormal exit code
|
||||
.output :
|
||||
int cc, condition code
|
||||
int cc, condition code
|
||||
.status_codes :
|
||||
CHF_F_MALLOC, FATAL, memory allocation failed
|
||||
CHF_F_MALLOC, FATAL, memory allocation failed
|
||||
.notes :
|
||||
1.1, 27-May-1996, creation
|
||||
|
||||
.- */
|
||||
int ChfStaticInit( /* Initialization with static message tables */
|
||||
const ChfChar *app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfTable *table, /* Static message table */
|
||||
const size_t table_size, /* Size of the message table */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
int ChfStaticInit( /* Initialization with static message tables */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfTable* table, /* Static message table */
|
||||
const size_t table_size, /* Size of the message table */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
)
|
||||
{
|
||||
ChfStaticContext *private_context;
|
||||
int cc;
|
||||
ChfStaticContext* private_context;
|
||||
int cc;
|
||||
|
||||
if((private_context =
|
||||
(ChfStaticContext *)malloc(sizeof(ChfStaticContext))) ==
|
||||
(ChfStaticContext *)NULL)
|
||||
cc = CHF_F_MALLOC;
|
||||
if ( ( private_context = ( ChfStaticContext* )malloc( sizeof( ChfStaticContext ) ) ) == ( ChfStaticContext* )NULL )
|
||||
cc = CHF_F_MALLOC;
|
||||
|
||||
else if((cc = ChfInit(app_name, options, (void *)private_context,
|
||||
StGetMessage, ExitMessage, condition_stack_size, handler_stack_size,
|
||||
exit_code)) != CHF_S_OK)
|
||||
free(private_context);
|
||||
else if ( ( cc = ChfInit( app_name, options, ( void* )private_context, StGetMessage, ExitMessage, condition_stack_size,
|
||||
handler_stack_size, exit_code ) ) != CHF_S_OK )
|
||||
free( private_context );
|
||||
|
||||
else
|
||||
{
|
||||
private_context->table = table;
|
||||
private_context->size = table_size;
|
||||
cc = CHF_S_OK;
|
||||
}
|
||||
else {
|
||||
private_context->table = table;
|
||||
private_context->size = table_size;
|
||||
cc = CHF_S_OK;
|
||||
}
|
||||
|
||||
return cc;
|
||||
return cc;
|
||||
}
|
||||
|
|
|
@ -35,20 +35,19 @@ static char rcs_id[] = "$Id: chf_top.c,v 2.2 2001/01/25 14:09:21 cibrario Exp $"
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Public functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -65,51 +64,50 @@ static char rcs_id[] = "$Id: chf_top.c,v 2.2 2001/01/25 14:09:21 cibrario Exp $"
|
|||
|
||||
|
||||
NOTE: During condition signalling, CHF creates a new, empty, condition group
|
||||
immediately before starting the invocation sequence of the condition
|
||||
handlers, as described in the documentation. Therefore
|
||||
ChfGetTopCondition(), if called from a condition handler, will return
|
||||
a pointer to the top condition generated during the handling ONLY, and
|
||||
NOT to the top condition of the condition group being signalled. The
|
||||
latter pointer is directly available, as an argument, to the condition
|
||||
handlers.
|
||||
immediately before starting the invocation sequence of the condition
|
||||
handlers, as described in the documentation. Therefore
|
||||
ChfGetTopCondition(), if called from a condition handler, will return
|
||||
a pointer to the top condition generated during the handling ONLY, and
|
||||
NOT to the top condition of the condition group being signalled. The
|
||||
latter pointer is directly available, as an argument, to the condition
|
||||
handlers.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_INIT
|
||||
if CHF hasn't been correctly initialized.
|
||||
if CHF hasn't been correctly initialized.
|
||||
|
||||
NOTE: The returned pointer is no longer valid when any other CHF function
|
||||
is called after ChfGetTopCondition().
|
||||
is called after ChfGetTopCondition().
|
||||
|
||||
.call :
|
||||
d = ChfGetTopCondition();
|
||||
d = ChfGetTopCondition();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
const ChfDescriptor *d, condition descriptor
|
||||
const ChfDescriptor *d, condition descriptor
|
||||
.status_codes :
|
||||
|
||||
|
||||
.notes :
|
||||
1.2, 17-May-1996, creation
|
||||
2.1, 24-May-2000, bug fix:
|
||||
- condition stack referenced incorrectly
|
||||
|
||||
.- */
|
||||
const ChfDescriptor *ChfGetTopCondition( /* Retrieve top condition */
|
||||
void
|
||||
)
|
||||
const ChfDescriptor* ChfGetTopCondition( /* Retrieve top condition */
|
||||
void )
|
||||
{
|
||||
ChfDescriptor *d;
|
||||
ChfDescriptor* d;
|
||||
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
if((d = chf_context.condition_sp) == chf_context.condition_base)
|
||||
{
|
||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
if ( ( d = chf_context.condition_sp ) == chf_context.condition_base ) {
|
||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* The top element of the condition group is the element immediately
|
||||
below the stack pointer.
|
||||
*/
|
||||
return d-1;
|
||||
/* The top element of the condition group is the element immediately
|
||||
below the stack pointer.
|
||||
*/
|
||||
return d - 1;
|
||||
}
|
||||
|
|
|
@ -28,20 +28,19 @@ static char rcs_id[] = "$Id: chf_win32.c,v 2.2 2001/01/25 14:11:58 cibrario Exp
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Global and static variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -51,46 +50,30 @@ static char rcs_id[] = "$Id: chf_win32.c,v 2.2 2001/01/25 14:11:58 cibrario Exp
|
|||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef struct
|
||||
{
|
||||
HINSTANCE instance; /* App. instance handle */
|
||||
ChfChar buffer[CHF_MAX_MESSAGE_LENGTH]; /* Temporary buffer */
|
||||
}
|
||||
ChfWin32Context;
|
||||
typedef struct {
|
||||
HINSTANCE instance; /* App. instance handle */
|
||||
ChfChar buffer[ CHF_MAX_MESSAGE_LENGTH ]; /* Temporary buffer */
|
||||
} ChfWin32Context;
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef _WIN32
|
||||
static const ChfChar *Win32GetMessage(
|
||||
void *private_context,
|
||||
const int module_id,
|
||||
const int condition_code,
|
||||
const ChfChar *default_message
|
||||
)
|
||||
static const ChfChar* Win32GetMessage( void* private_context, const int module_id, const int condition_code,
|
||||
const ChfChar* default_message )
|
||||
{
|
||||
if(!LoadString(
|
||||
((ChfWin32Context *)private_context)->instance,
|
||||
module_id*1000 + condition_code,
|
||||
((ChfWin32Context *)private_context)->buffer,
|
||||
CHF_MAX_MESSAGE_LENGTH-1))
|
||||
return default_message;
|
||||
if ( !LoadString( ( ( ChfWin32Context* )private_context )->instance, module_id * 1000 + condition_code,
|
||||
( ( ChfWin32Context* )private_context )->buffer, CHF_MAX_MESSAGE_LENGTH - 1 ) )
|
||||
return default_message;
|
||||
|
||||
return ((ChfWin32Context *)private_context)->buffer;
|
||||
return ( ( ChfWin32Context* )private_context )->buffer;
|
||||
}
|
||||
|
||||
static void ExitMessage(
|
||||
void *private_context
|
||||
)
|
||||
{
|
||||
free(private_context);
|
||||
}
|
||||
static void ExitMessage( void* private_context ) { free( private_context ); }
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Public functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -109,7 +92,7 @@ static void ExitMessage(
|
|||
other CHF initialization routines before using any other CHF function.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_DUP_INIT
|
||||
if CHF has already been initialized before.
|
||||
if CHF has already been initialized before.
|
||||
|
||||
WIN32:
|
||||
|
||||
|
@ -124,68 +107,63 @@ static void ExitMessage(
|
|||
0 <= module_id <= 64
|
||||
|
||||
.call :
|
||||
cc = ChfWin32Init(app_name, options,
|
||||
msgcat_name,
|
||||
condition_stack_size, handler_stack_size,
|
||||
exit_code);
|
||||
cc = ChfWin32Init(app_name, options,
|
||||
msgcat_name,
|
||||
condition_stack_size, handler_stack_size,
|
||||
exit_code);
|
||||
.input :
|
||||
const ChfChar *app_name, Application's name
|
||||
const ChfOptions options, Options
|
||||
HINSTANCE instance, App. instance handle
|
||||
const int condition_stack_size, Size of the condition stack
|
||||
const int handler_stack_size, Size of the handler stack
|
||||
const int exit_code, Abnormal exit code
|
||||
const ChfChar *app_name, Application's name
|
||||
const ChfOptions options, Options
|
||||
HINSTANCE instance, App. instance handle
|
||||
const int condition_stack_size, Size of the condition stack
|
||||
const int handler_stack_size, Size of the handler stack
|
||||
const int exit_code, Abnormal exit code
|
||||
.output :
|
||||
int cc, condition code
|
||||
int cc, condition code
|
||||
.status_codes :
|
||||
CHF_F_MALLOC, FATAL, memory allocation failed
|
||||
CHF_F_NOT_AVAILABLE, FATAL, function not available
|
||||
CHF_F_MALLOC, FATAL, memory allocation failed
|
||||
CHF_F_NOT_AVAILABLE, FATAL, function not available
|
||||
.notes :
|
||||
2.2, 19-Jan-2001, creation
|
||||
|
||||
.- */
|
||||
int ChfWin32Init( /* Initialization within _WIN32 */
|
||||
const ChfChar *app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
int ChfWin32Init( /* Initialization within _WIN32 */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
#ifndef _WIN32
|
||||
void *instance, /* Fake arguments */
|
||||
void* instance, /* Fake arguments */
|
||||
#else
|
||||
HINSTANCE instance, /* App. instance handle */
|
||||
HINSTANCE instance, /* App. instance handle */
|
||||
#endif
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
/* This function is available only in Win32 */
|
||||
return CHF_F_NOT_AVAILABLE;
|
||||
/* This function is available only in Win32 */
|
||||
return CHF_F_NOT_AVAILABLE;
|
||||
|
||||
#else
|
||||
ChfWin32Context *private_context;
|
||||
int cc;
|
||||
ChfWin32Context* private_context;
|
||||
int cc;
|
||||
|
||||
if((private_context =
|
||||
(ChfWin32Context *)malloc(sizeof(ChfWin32Context))) ==
|
||||
(ChfWin32Context *)NULL)
|
||||
cc = CHF_F_MALLOC;
|
||||
if ( ( private_context = ( ChfWin32Context* )malloc( sizeof( ChfWin32Context ) ) ) == ( ChfWin32Context* )NULL )
|
||||
cc = CHF_F_MALLOC;
|
||||
|
||||
else if((cc = ChfInit(app_name, options, (void *)private_context,
|
||||
Win32GetMessage, ExitMessage, condition_stack_size, handler_stack_size,
|
||||
exit_code)) != CHF_S_OK)
|
||||
{
|
||||
free(private_context);
|
||||
}
|
||||
else if ( ( cc = ChfInit( app_name, options, ( void* )private_context, Win32GetMessage, ExitMessage, condition_stack_size,
|
||||
handler_stack_size, exit_code ) ) != CHF_S_OK ) {
|
||||
free( private_context );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Save Win32 specific context items into private Chf context */
|
||||
private_context->instance = instance;
|
||||
else {
|
||||
/* Save Win32 specific context items into private Chf context */
|
||||
private_context->instance = instance;
|
||||
|
||||
cc = CHF_S_OK;
|
||||
}
|
||||
cc = CHF_S_OK;
|
||||
}
|
||||
|
||||
return cc;
|
||||
return cc;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
14
src/libChf/resource.h
Executable file → Normal file
14
src/libChf/resource.h
Executable file → Normal file
|
@ -4,12 +4,12 @@
|
|||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
# ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
# define _APS_NEXT_RESOURCE_VALUE 101
|
||||
# define _APS_NEXT_COMMAND_VALUE 40001
|
||||
# define _APS_NEXT_CONTROL_VALUE 1000
|
||||
# define _APS_NEXT_SYMED_VALUE 101
|
||||
# endif
|
||||
#endif
|
||||
|
|
|
@ -11,64 +11,55 @@
|
|||
#include <setjmp.h>
|
||||
|
||||
#ifdef _REENTRANT
|
||||
#include <pthread.h>
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "Chf.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int st;
|
||||
const char *msg;
|
||||
const char* msg;
|
||||
const ChfDescriptor *d, *e;
|
||||
|
||||
puts("test01");
|
||||
puts( "test01" );
|
||||
|
||||
system("gencat test01.cat test01.msf");
|
||||
system("gencat test01.cat chf.msf");
|
||||
system( "gencat test01.cat test01.msf" );
|
||||
system( "gencat test01.cat chf.msf" );
|
||||
|
||||
/* Initialization */
|
||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat", 50, 10, 1))
|
||||
exit(st);
|
||||
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", 50, 10, 1 ) )
|
||||
exit( st );
|
||||
|
||||
/* ChfGetMessage:
|
||||
message (CHF_MODULE_ID, 1) exists, (CHF_MODULE_ID, 2) does not
|
||||
*/
|
||||
msg = ChfGetMessage(CHF_MODULE_ID, 1, "Default_1");
|
||||
if(strcmp(msg, "Set_255,Message_1")) exit(EXIT_FAILURE);
|
||||
msg = ChfGetMessage(CHF_MODULE_ID, 2, "Default_2");
|
||||
if(strcmp(msg, "Default_2")) exit(EXIT_FAILURE);
|
||||
msg = ChfGetMessage( CHF_MODULE_ID, 1, "Default_1" );
|
||||
if ( strcmp( msg, "Set_255,Message_1" ) )
|
||||
exit( EXIT_FAILURE );
|
||||
msg = ChfGetMessage( CHF_MODULE_ID, 2, "Default_2" );
|
||||
if ( strcmp( msg, "Default_2" ) )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate a condition and check descriptor; this is line 46 */
|
||||
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
||||
|
||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
||||
if(
|
||||
d->module_id != CHF_MODULE_ID
|
||||
|| d->condition_code != 3
|
||||
|| d->severity != CHF_WARNING
|
||||
|| d->line_number != 46
|
||||
|| strcmp(d->file_name, "test01.c")
|
||||
|| strcmp(d->message, "Set_255,Arg_456,Message_3")
|
||||
|| d->next != NULL
|
||||
) exit(EXIT_FAILURE);
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 3 || d->severity != CHF_WARNING || d->line_number != 46 ||
|
||||
strcmp( d->file_name, "test01.c" ) || strcmp( d->message, "Set_255,Arg_456,Message_3" ) || d->next != NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate another condition and check; this is line 60 */
|
||||
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
||||
|
||||
if((e = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
||||
if(
|
||||
e->module_id != CHF_MODULE_ID
|
||||
|| e->condition_code != 4
|
||||
|| e->severity != CHF_INFO
|
||||
|| e->line_number != 60
|
||||
|| strcmp(e->file_name, "test01.c")
|
||||
|| strcmp(e->message, "Set_255,Arg_arg,Message_4")
|
||||
|| e->next != d
|
||||
) exit(EXIT_FAILURE);
|
||||
if ( ( e = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
if ( e->module_id != CHF_MODULE_ID || e->condition_code != 4 || e->severity != CHF_INFO || e->line_number != 60 ||
|
||||
strcmp( e->file_name, "test01.c" ) || strcmp( e->message, "Set_255,Arg_arg,Message_4" ) || e->next != d )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Discard the previous condition group and create a new one */
|
||||
ChfDiscard();
|
||||
|
@ -76,18 +67,13 @@ int main(int argc, char *argv[])
|
|||
/* This is line 77 */
|
||||
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||
|
||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
||||
if(
|
||||
d->module_id != CHF_MODULE_ID
|
||||
|| d->condition_code != 5
|
||||
|| d->severity != CHF_ERROR
|
||||
|| d->line_number != 77
|
||||
|| strcmp(d->file_name, "test01.c")
|
||||
|| strcmp(d->message, "Set_255,Arg_456-789,Message_5")
|
||||
|| d->next != NULL
|
||||
) exit(EXIT_FAILURE);
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 5 || d->severity != CHF_ERROR || d->line_number != 77 ||
|
||||
strcmp( d->file_name, "test01.c" ) || strcmp( d->message, "Set_255,Arg_456-789,Message_5" ) || d->next != NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Exit Chf */
|
||||
ChfExit();
|
||||
exit(EXIT_SUCCESS);
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
|
|
@ -11,54 +11,45 @@
|
|||
#include <setjmp.h>
|
||||
|
||||
#ifdef _REENTRANT
|
||||
#include <pthread.h>
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "Chf.h"
|
||||
|
||||
|
||||
void *task(void *arg)
|
||||
void* task( void* arg )
|
||||
{
|
||||
const char *msg;
|
||||
const char* msg;
|
||||
const ChfDescriptor *d, *e;
|
||||
|
||||
printf("\tThread %d\n", (int)arg);
|
||||
printf( "\tThread %d\n", ( int )arg );
|
||||
|
||||
/* message (CHF_MODULE_ID, 1) exists, (CHF_MODULE_ID, 2) does not */
|
||||
msg = ChfGetMessage(CHF_MODULE_ID, 1, "Default_1");
|
||||
if(strcmp(msg, "Set_255,Message_1")) exit(EXIT_FAILURE);
|
||||
msg = ChfGetMessage(CHF_MODULE_ID, 2, "Default_2");
|
||||
if(strcmp(msg, "Default_2")) exit(EXIT_FAILURE);
|
||||
msg = ChfGetMessage( CHF_MODULE_ID, 1, "Default_1" );
|
||||
if ( strcmp( msg, "Set_255,Message_1" ) )
|
||||
exit( EXIT_FAILURE );
|
||||
msg = ChfGetMessage( CHF_MODULE_ID, 2, "Default_2" );
|
||||
if ( strcmp( msg, "Default_2" ) )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate a condition and check descriptor; this is line 36 */
|
||||
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
||||
|
||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
||||
if(
|
||||
d->module_id != CHF_MODULE_ID
|
||||
|| d->condition_code != 3
|
||||
|| d->severity != CHF_WARNING
|
||||
|| d->line_number != 36
|
||||
|| strcmp(d->file_name, "test02.c")
|
||||
|| strcmp(d->message, "Set_255,Arg_456,Message_3")
|
||||
|| d->next != NULL
|
||||
) exit(EXIT_FAILURE);
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 3 || d->severity != CHF_WARNING || d->line_number != 36 ||
|
||||
strcmp( d->file_name, "test02.c" ) || strcmp( d->message, "Set_255,Arg_456,Message_3" ) || d->next != NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate another condition and check; this is line 50 */
|
||||
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
||||
|
||||
if((e = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
||||
if(
|
||||
e->module_id != CHF_MODULE_ID
|
||||
|| e->condition_code != 4
|
||||
|| e->severity != CHF_INFO
|
||||
|| e->line_number != 50
|
||||
|| strcmp(e->file_name, "test02.c")
|
||||
|| strcmp(e->message, "Set_255,Arg_arg,Message_4")
|
||||
|| e->next != d
|
||||
) exit(EXIT_FAILURE);
|
||||
if ( ( e = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
if ( e->module_id != CHF_MODULE_ID || e->condition_code != 4 || e->severity != CHF_INFO || e->line_number != 50 ||
|
||||
strcmp( e->file_name, "test02.c" ) || strcmp( e->message, "Set_255,Arg_arg,Message_4" ) || e->next != d )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Discard the previous condition group and create a new one */
|
||||
ChfDiscard();
|
||||
|
@ -66,56 +57,49 @@ void *task(void *arg)
|
|||
/* This is line 67 */
|
||||
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||
|
||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
||||
if(
|
||||
d->module_id != CHF_MODULE_ID
|
||||
|| d->condition_code != 5
|
||||
|| d->severity != CHF_ERROR
|
||||
|| d->line_number != 67
|
||||
|| strcmp(d->file_name, "test02.c")
|
||||
|| strcmp(d->message, "Set_255,Arg_456-789,Message_5")
|
||||
|| d->next != NULL
|
||||
) exit(EXIT_FAILURE);
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 5 || d->severity != CHF_ERROR || d->line_number != 67 ||
|
||||
strcmp( d->file_name, "test02.c" ) || strcmp( d->message, "Set_255,Arg_456-789,Message_5" ) || d->next != NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
return (void *)0;
|
||||
return ( void* )0;
|
||||
}
|
||||
|
||||
#define N_THREADS 50
|
||||
#define N_THREADS 50
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int st;
|
||||
int i;
|
||||
void *ret;
|
||||
void* ret;
|
||||
#ifdef _REENTRANT
|
||||
pthread_t t[N_THREADS];
|
||||
pthread_t t[ N_THREADS ];
|
||||
#endif
|
||||
|
||||
puts("test02");
|
||||
puts( "test02" );
|
||||
|
||||
#ifdef _REENTRANT
|
||||
/* Initialization */
|
||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat", 50, 10, 1))
|
||||
exit(st);
|
||||
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", 50, 10, 1 ) )
|
||||
exit( st );
|
||||
|
||||
/* Create */
|
||||
for(i=0; i<N_THREADS; i++)
|
||||
if(st = pthread_create(&(t[i]), NULL, task, (void *)i))
|
||||
{
|
||||
printf("pthread_create: error %d", st);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for ( i = 0; i < N_THREADS; i++ )
|
||||
if ( st = pthread_create( &( t[ i ] ), NULL, task, ( void* )i ) ) {
|
||||
printf( "pthread_create: error %d", st );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* Join */
|
||||
for(i=0; i<N_THREADS; i++)
|
||||
if(st = pthread_join(t[i], &ret))
|
||||
{
|
||||
printf("pthread_join: error %d", st);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for ( i = 0; i < N_THREADS; i++ )
|
||||
if ( st = pthread_join( t[ i ], &ret ) ) {
|
||||
printf( "pthread_join: error %d", st );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* Exit Chf */
|
||||
ChfExit();
|
||||
#endif
|
||||
exit(EXIT_SUCCESS);
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
|
|
@ -14,77 +14,74 @@
|
|||
#include <setjmp.h>
|
||||
|
||||
#ifdef _REENTRANT
|
||||
#include <pthread.h>
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "Chf.h"
|
||||
|
||||
|
||||
void *task(void *arg)
|
||||
void* task( void* arg )
|
||||
{
|
||||
const char *msg;
|
||||
const char* msg;
|
||||
const ChfDescriptor *d, *e;
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep(1);
|
||||
sleep( 1 );
|
||||
|
||||
printf("\tThread %d\n", (int)arg);
|
||||
printf( "\tThread %d\n", ( int )arg );
|
||||
|
||||
/* Generate a condition group and signal it */
|
||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
||||
ChfCondition 7, CHF_INFO, (int)arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep(1);
|
||||
sleep( 1 );
|
||||
ChfSignal();
|
||||
|
||||
return (void *)0;
|
||||
return ( void* )0;
|
||||
}
|
||||
|
||||
#define N_THREADS 50
|
||||
#define N_THREADS 50
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int st;
|
||||
int i;
|
||||
void *ret;
|
||||
void* ret;
|
||||
|
||||
#ifdef _REENTRANT
|
||||
pthread_t t[N_THREADS];
|
||||
pthread_t t[ N_THREADS ];
|
||||
#endif
|
||||
|
||||
puts("test03");
|
||||
puts( "test03" );
|
||||
|
||||
/* Initialization */
|
||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat", 50, 10, 1))
|
||||
exit(st);
|
||||
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", 50, 10, 1 ) )
|
||||
exit( st );
|
||||
|
||||
#ifdef _REENTRANT
|
||||
/* Create */
|
||||
for(i=0; i<N_THREADS; i++)
|
||||
if(pthread_create(&(t[i]), NULL, task, (void *)i))
|
||||
{
|
||||
perror("pthread_create");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for ( i = 0; i < N_THREADS; i++ )
|
||||
if ( pthread_create( &( t[ i ] ), NULL, task, ( void* )i ) ) {
|
||||
perror( "pthread_create" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* Join */
|
||||
for(i=0; i<N_THREADS; i++)
|
||||
if(pthread_join(t[i], &ret))
|
||||
{
|
||||
perror("pthread_join");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for ( i = 0; i < N_THREADS; i++ )
|
||||
if ( pthread_join( t[ i ], &ret ) ) {
|
||||
perror( "pthread_join" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
#else
|
||||
task((void *)0);
|
||||
task( ( void* )0 );
|
||||
#endif
|
||||
|
||||
/* Exit Chf */
|
||||
ChfExit();
|
||||
exit(EXIT_SUCCESS);
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
|
|
@ -14,193 +14,161 @@
|
|||
#include <setjmp.h>
|
||||
|
||||
#ifdef _REENTRANT
|
||||
#include <pthread.h>
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "Chf.h"
|
||||
|
||||
struct tdata_s
|
||||
{
|
||||
struct tdata_s {
|
||||
const ChfDescriptor *d, *e;
|
||||
int phase;
|
||||
};
|
||||
|
||||
ChfAction h1(
|
||||
const ChfDescriptor *c,
|
||||
const ChfState s,
|
||||
ChfPointer p
|
||||
)
|
||||
ChfAction h1( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
struct tdata_s *tdata_p = (struct tdata_s *)p;
|
||||
struct tdata_s* tdata_p = ( struct tdata_s* )p;
|
||||
ChfAction action;
|
||||
|
||||
if(c != tdata_p->e ||
|
||||
ChfGetNextDescriptor(c) != tdata_p->d)
|
||||
{
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d ) {
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
|
||||
else
|
||||
action = CHF_CONTINUE;
|
||||
action = CHF_CONTINUE;
|
||||
|
||||
return action;
|
||||
|
||||
}
|
||||
|
||||
ChfAction h2(
|
||||
const ChfDescriptor *c,
|
||||
const ChfState s,
|
||||
ChfPointer p
|
||||
)
|
||||
ChfAction h2( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
struct tdata_s *tdata_p = (struct tdata_s *)p;
|
||||
struct tdata_s* tdata_p = ( struct tdata_s* )p;
|
||||
ChfAction action;
|
||||
|
||||
switch(s)
|
||||
{
|
||||
case CHF_SIGNALING:
|
||||
{
|
||||
if(c != tdata_p->e
|
||||
|| ChfGetNextDescriptor(c) != tdata_p->d
|
||||
|| (tdata_p->phase != 2 && tdata_p->phase != 4))
|
||||
{
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
switch ( s ) {
|
||||
case CHF_SIGNALING:
|
||||
{
|
||||
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d || ( tdata_p->phase != 2 && tdata_p->phase != 4 ) ) {
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
action = (ChfGetConditionCode(c) != 8 ? CHF_CONTINUE : CHF_UNWIND);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHF_UNWINDING:
|
||||
{
|
||||
if(tdata_p->phase != 4) exit(EXIT_FAILURE);
|
||||
tdata_p->phase = 5;
|
||||
action = CHF_CONTINUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
action = ( ChfGetConditionCode( c ) != 8 ? CHF_CONTINUE : CHF_UNWIND );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHF_UNWINDING:
|
||||
{
|
||||
if ( tdata_p->phase != 4 )
|
||||
exit( EXIT_FAILURE );
|
||||
tdata_p->phase = 5;
|
||||
action = CHF_CONTINUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
ChfAction h3(
|
||||
const ChfDescriptor *c,
|
||||
const ChfState s,
|
||||
ChfPointer p
|
||||
)
|
||||
ChfAction h3( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
struct tdata_s *tdata_p = (struct tdata_s *)p;
|
||||
struct tdata_s* tdata_p = ( struct tdata_s* )p;
|
||||
ChfAction action;
|
||||
|
||||
/* This handler must be invoked only during the first signal */
|
||||
if(tdata_p->phase != 3) exit(EXIT_FAILURE);
|
||||
if ( tdata_p->phase != 3 )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
switch(s)
|
||||
{
|
||||
case CHF_SIGNALING:
|
||||
{
|
||||
if(ChfGetConditionCode(c) != 9 ||
|
||||
ChfGetNextDescriptor(c) != NULL)
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
switch ( s ) {
|
||||
case CHF_SIGNALING:
|
||||
{
|
||||
if ( ChfGetConditionCode( c ) != 9 || ChfGetNextDescriptor( c ) != NULL ) {
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
tdata_p->phase = 4;
|
||||
action = CHF_CONTINUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
tdata_p->phase = 4;
|
||||
action = CHF_CONTINUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
ChfAction h4(
|
||||
const ChfDescriptor *c,
|
||||
const ChfState s,
|
||||
ChfPointer p
|
||||
)
|
||||
ChfAction h4( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
struct tdata_s *tdata_p = (struct tdata_s *)p;
|
||||
struct tdata_s* tdata_p = ( struct tdata_s* )p;
|
||||
ChfAction action;
|
||||
|
||||
/* This handler must be invoked only during the first signal */
|
||||
if(tdata_p->phase != 2) exit(EXIT_FAILURE);
|
||||
if ( tdata_p->phase != 2 )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
switch(s)
|
||||
{
|
||||
case CHF_SIGNALING:
|
||||
{
|
||||
if(c != tdata_p->e
|
||||
|| ChfGetNextDescriptor(c) != tdata_p->d)
|
||||
{
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
switch ( s ) {
|
||||
case CHF_SIGNALING:
|
||||
{
|
||||
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d ) {
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* This generates a new group and signals it */
|
||||
tdata_p->phase = 3;
|
||||
ChfCondition 9, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
else {
|
||||
/* This generates a new group and signals it */
|
||||
tdata_p->phase = 3;
|
||||
ChfCondition 9, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
if(tdata_p->phase != 4) exit(EXIT_FAILURE);
|
||||
tdata_p->phase = 5;
|
||||
if ( tdata_p->phase != 4 )
|
||||
exit( EXIT_FAILURE );
|
||||
tdata_p->phase = 5;
|
||||
|
||||
if(c != tdata_p->e
|
||||
|| ChfGetNextDescriptor(c) != tdata_p->d)
|
||||
{
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
else
|
||||
action = CHF_CONTINUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d ) {
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
} else
|
||||
action = CHF_CONTINUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
void *task(void *arg)
|
||||
void* task( void* arg )
|
||||
{
|
||||
volatile struct tdata_s tdata;
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep(1);
|
||||
sleep( 1 );
|
||||
|
||||
printf("\tThread %d\n", (int)arg);
|
||||
printf( "\tThread %d\n", ( int )arg );
|
||||
|
||||
/* Push the handler */
|
||||
ChfPushHandler(h1, NULL, (ChfPointer)(&tdata));
|
||||
ChfPushHandler( h1, NULL, ( ChfPointer )( &tdata ) );
|
||||
|
||||
/* Generate a condition group and signal it */
|
||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
ChfCondition 7, CHF_INFO, (int)arg ChfEnd;
|
||||
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep(1);
|
||||
sleep( 1 );
|
||||
ChfSignal();
|
||||
|
||||
/* Pop the handler */
|
||||
|
@ -210,122 +178,117 @@ void *task(void *arg)
|
|||
and signal it; this checks that the handler has actually been
|
||||
removed.
|
||||
*/
|
||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.d = NULL;
|
||||
ChfCondition 7, CHF_INFO, (int)arg ChfEnd;
|
||||
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.e = NULL;
|
||||
ChfSignal();
|
||||
|
||||
/* Conditional unwind test */
|
||||
{
|
||||
sigjmp_buf jb;
|
||||
sigjmp_buf jb;
|
||||
|
||||
tdata.phase = 0;
|
||||
if(setjmp(jb) == 0)
|
||||
{
|
||||
ChfPushHandler(h2, jb, (ChfPointer)(&tdata));
|
||||
tdata.phase = 0;
|
||||
if ( setjmp( jb ) == 0 ) {
|
||||
ChfPushHandler( h2, jb, ( ChfPointer )( &tdata ) );
|
||||
|
||||
/* Generate a condition group and signal it */
|
||||
tdata.phase = 1;
|
||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
ChfCondition 7, CHF_INFO, (int)arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
/* Generate a condition group and signal it */
|
||||
tdata.phase = 1;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
|
||||
/* This does not trigger an unwind */
|
||||
tdata.phase = 2;
|
||||
ChfSignal();
|
||||
/* This does not trigger an unwind */
|
||||
tdata.phase = 2;
|
||||
ChfSignal();
|
||||
|
||||
tdata.phase = 3;
|
||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
ChfCondition 8, CHF_INFO, (int)arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
tdata.phase = 3;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
ChfCondition 8, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
|
||||
/* This MUST trigger an unwind */
|
||||
tdata.phase = 4;
|
||||
ChfSignal();
|
||||
/* This MUST trigger an unwind */
|
||||
tdata.phase = 4;
|
||||
ChfSignal();
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unwind */
|
||||
if(tdata.phase != 5)
|
||||
exit(EXIT_FAILURE);
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
ChfPopHandler();
|
||||
}
|
||||
} else {
|
||||
/* Unwind */
|
||||
if ( tdata.phase != 5 )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
ChfPopHandler();
|
||||
}
|
||||
}
|
||||
|
||||
/* Condition generation and signal while a signal is in progress;
|
||||
this requires two handlers.
|
||||
*/
|
||||
{
|
||||
tdata.phase = 0;
|
||||
tdata.phase = 0;
|
||||
|
||||
ChfPushHandler(h3, NULL, (ChfPointer)&tdata);
|
||||
ChfPushHandler(h4, NULL, (ChfPointer)&tdata);
|
||||
ChfPushHandler( h3, NULL, ( ChfPointer )&tdata );
|
||||
ChfPushHandler( h4, NULL, ( ChfPointer )&tdata );
|
||||
|
||||
tdata.phase = 1;
|
||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
ChfCondition 7, CHF_INFO, (int)arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
tdata.phase = 1;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
|
||||
tdata.phase = 2;
|
||||
ChfSignal();
|
||||
tdata.phase = 2;
|
||||
ChfSignal();
|
||||
|
||||
if(tdata.phase != 5)
|
||||
exit(EXIT_FAILURE);
|
||||
if ( tdata.phase != 5 )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
ChfPopHandler();
|
||||
ChfPopHandler();
|
||||
ChfPopHandler();
|
||||
ChfPopHandler();
|
||||
}
|
||||
|
||||
return (void *)0;
|
||||
return ( void* )0;
|
||||
}
|
||||
|
||||
#define N_THREADS 50
|
||||
#define N_THREADS 50
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int st;
|
||||
int i;
|
||||
void *ret;
|
||||
void* ret;
|
||||
|
||||
#ifdef _REENTRANT
|
||||
pthread_t t[N_THREADS];
|
||||
pthread_t t[ N_THREADS ];
|
||||
#endif
|
||||
|
||||
puts("test04");
|
||||
puts( "test04" );
|
||||
|
||||
/* Initialization */
|
||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat", 50, 10, 1))
|
||||
exit(st);
|
||||
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", 50, 10, 1 ) )
|
||||
exit( st );
|
||||
|
||||
#ifdef _REENTRANT
|
||||
/* Create */
|
||||
for(i=0; i<N_THREADS; i++)
|
||||
if(pthread_create(&(t[i]), NULL, task, (void *)i))
|
||||
{
|
||||
perror("pthread_create");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for ( i = 0; i < N_THREADS; i++ )
|
||||
if ( pthread_create( &( t[ i ] ), NULL, task, ( void* )i ) ) {
|
||||
perror( "pthread_create" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* Join */
|
||||
for(i=0; i<N_THREADS; i++)
|
||||
if(pthread_join(t[i], &ret))
|
||||
{
|
||||
perror("pthread_join");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for ( i = 0; i < N_THREADS; i++ )
|
||||
if ( pthread_join( t[ i ], &ret ) ) {
|
||||
perror( "pthread_join" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
#else
|
||||
task((void *)0);
|
||||
task( ( void* )0 );
|
||||
#endif
|
||||
|
||||
/* Exit Chf */
|
||||
ChfExit();
|
||||
exit(EXIT_SUCCESS);
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
|
|
@ -14,63 +14,45 @@
|
|||
#include <setjmp.h>
|
||||
|
||||
#ifdef _REENTRANT
|
||||
#include <pthread.h>
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "Chf.h"
|
||||
|
||||
#define H_STACK_SIZE 10
|
||||
#define C_STACK_SIZE 30
|
||||
#define H_STACK_SIZE 10
|
||||
#define C_STACK_SIZE 30
|
||||
|
||||
/* Dummy handler; pushed only to verify that the handler stack overflow
|
||||
checks are correct.
|
||||
*/
|
||||
ChfAction h1(
|
||||
const ChfDescriptor *c,
|
||||
const ChfState s,
|
||||
ChfPointer p
|
||||
)
|
||||
{
|
||||
return CHF_RESIGNAL;
|
||||
}
|
||||
ChfAction h1( const ChfDescriptor* c, const ChfState s, ChfPointer p ) { return CHF_RESIGNAL; }
|
||||
|
||||
/* Overflow check handler; it unwinds if the CHF_F_HDLR_STACK_FULL
|
||||
condition is signalled exactly after H_STACK_SIZE-2 invocations
|
||||
of ChfPushHandler(), it resignals a modified condition if the
|
||||
condition is signalled too early
|
||||
*/
|
||||
ChfAction h2(
|
||||
const ChfDescriptor *c,
|
||||
const ChfState s,
|
||||
ChfPointer p
|
||||
)
|
||||
ChfAction h2( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
int push_count = *((int *)p);
|
||||
int push_count = *( ( int* )p );
|
||||
ChfAction action;
|
||||
|
||||
if(s == CHF_SIGNALING)
|
||||
{
|
||||
if(ChfGetModuleId(c) == CHF_SET
|
||||
&& ChfGetConditionCode(c) == CHF_F_HDLR_STACK_FULL)
|
||||
{
|
||||
/* Handler stack is full; check correctness of the descriptor */
|
||||
if(push_count == H_STACK_SIZE-2
|
||||
&& ChfGetNextDescriptor(c) == NULL
|
||||
&& ChfGetSeverity(c) == CHF_FATAL)
|
||||
action = CHF_UNWIND;
|
||||
else
|
||||
{
|
||||
ChfCondition 11, CHF_FATAL, push_count, H_STACK_SIZE-2
|
||||
ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
}
|
||||
if ( s == CHF_SIGNALING ) {
|
||||
if ( ChfGetModuleId( c ) == CHF_SET && ChfGetConditionCode( c ) == CHF_F_HDLR_STACK_FULL ) {
|
||||
/* Handler stack is full; check correctness of the descriptor */
|
||||
if ( push_count == H_STACK_SIZE - 2 && ChfGetNextDescriptor( c ) == NULL && ChfGetSeverity( c ) == CHF_FATAL )
|
||||
action = CHF_UNWIND;
|
||||
else {
|
||||
ChfCondition 11, CHF_FATAL, push_count, H_STACK_SIZE - 2 ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
action = CHF_RESIGNAL;
|
||||
action = CHF_RESIGNAL;
|
||||
|
||||
return action;
|
||||
}
|
||||
|
@ -80,68 +62,55 @@ ChfAction h2(
|
|||
of ChfCondition, it resignals a modified condition if the
|
||||
condition is signalled too early
|
||||
*/
|
||||
ChfAction h3(
|
||||
const ChfDescriptor *c,
|
||||
const ChfState s,
|
||||
ChfPointer p
|
||||
)
|
||||
ChfAction h3( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
int push_count = *((int *)p);
|
||||
int push_count = *( ( int* )p );
|
||||
ChfAction action;
|
||||
|
||||
if(s == CHF_SIGNALING)
|
||||
{
|
||||
if(ChfGetModuleId(c) == CHF_SET
|
||||
&& ChfGetConditionCode(c) == CHF_F_COND_STACK_FULL)
|
||||
{
|
||||
/* Handler stack is full; check correctness of the descriptor */
|
||||
if(push_count == C_STACK_SIZE
|
||||
&& ChfGetNextDescriptor(c) == NULL
|
||||
&& ChfGetSeverity(c) == CHF_FATAL)
|
||||
action = CHF_UNWIND;
|
||||
else
|
||||
{
|
||||
ChfCondition 12, CHF_FATAL, push_count, C_STACK_SIZE
|
||||
ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
}
|
||||
if ( s == CHF_SIGNALING ) {
|
||||
if ( ChfGetModuleId( c ) == CHF_SET && ChfGetConditionCode( c ) == CHF_F_COND_STACK_FULL ) {
|
||||
/* Handler stack is full; check correctness of the descriptor */
|
||||
if ( push_count == C_STACK_SIZE && ChfGetNextDescriptor( c ) == NULL && ChfGetSeverity( c ) == CHF_FATAL )
|
||||
action = CHF_UNWIND;
|
||||
else {
|
||||
ChfCondition 12, CHF_FATAL, push_count, C_STACK_SIZE ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
action = CHF_RESIGNAL;
|
||||
action = CHF_RESIGNAL;
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
|
||||
void *task(void *arg)
|
||||
void* task( void* arg )
|
||||
{
|
||||
int push_count = 0;
|
||||
sigjmp_buf jb;
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep(1);
|
||||
sleep( 1 );
|
||||
|
||||
printf("\tThread %d\n", (int)arg);
|
||||
printf( "\tThread %d\n", ( int )arg );
|
||||
|
||||
/* Check handler stack overflow checks */
|
||||
if(sigsetjmp(jb, 1) == 0)
|
||||
{
|
||||
int i;
|
||||
if ( sigsetjmp( jb, 1 ) == 0 ) {
|
||||
int i;
|
||||
|
||||
/* Push the handler */
|
||||
ChfPushHandler(h2, jb, (ChfPointer)(&push_count));
|
||||
/* Push the handler */
|
||||
ChfPushHandler( h2, jb, ( ChfPointer )( &push_count ) );
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep(1);
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep( 1 );
|
||||
|
||||
/* Push dummy handlers until an error should occur */
|
||||
for(; push_count<H_STACK_SIZE-1; push_count++)
|
||||
ChfPushHandler(h1, NULL, NULL);
|
||||
/* Push dummy handlers until an error should occur */
|
||||
for ( ; push_count < H_STACK_SIZE - 1; push_count++ )
|
||||
ChfPushHandler( h1, NULL, NULL );
|
||||
|
||||
/* No error? Bad! */
|
||||
return (void *)EXIT_FAILURE;
|
||||
/* No error? Bad! */
|
||||
return ( void* )EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Flow control returns here if 'handler stack full' was signalled
|
||||
|
@ -149,22 +118,21 @@ void *task(void *arg)
|
|||
Check condition stack overflow checks
|
||||
*/
|
||||
push_count = 0;
|
||||
if(sigsetjmp(jb, 1) == 0)
|
||||
{
|
||||
int i;
|
||||
if ( sigsetjmp( jb, 1 ) == 0 ) {
|
||||
int i;
|
||||
|
||||
/* Push the handler */
|
||||
ChfPushHandler(h3, jb, (ChfPointer)(&push_count));
|
||||
/* Push the handler */
|
||||
ChfPushHandler( h3, jb, ( ChfPointer )( &push_count ) );
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep(1);
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep( 1 );
|
||||
|
||||
/* Push dummy conditions until an error should occur */
|
||||
for(; push_count<=C_STACK_SIZE; push_count++)
|
||||
ChfCondition 1, CHF_INFO ChfEnd;
|
||||
/* Push dummy conditions until an error should occur */
|
||||
for ( ; push_count <= C_STACK_SIZE; push_count++ )
|
||||
ChfCondition 1, CHF_INFO ChfEnd;
|
||||
|
||||
/* No error? Bad! */
|
||||
return (void *)EXIT_FAILURE;
|
||||
/* No error? Bad! */
|
||||
return ( void* )EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Flow control returns here if 'condition stack full' was signalled
|
||||
|
@ -173,75 +141,67 @@ void *task(void *arg)
|
|||
conditions were left out in the previous check.
|
||||
*/
|
||||
push_count = 0;
|
||||
if(sigsetjmp(jb, 1) == 0)
|
||||
{
|
||||
int i;
|
||||
if ( sigsetjmp( jb, 1 ) == 0 ) {
|
||||
int i;
|
||||
|
||||
/* Push the handler */
|
||||
ChfPushHandler(h3, jb, (ChfPointer)(&push_count));
|
||||
/* Push the handler */
|
||||
ChfPushHandler( h3, jb, ( ChfPointer )( &push_count ) );
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep(1);
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep( 1 );
|
||||
|
||||
/* Push dummy conditions until an error should occur */
|
||||
for(; push_count<=C_STACK_SIZE; push_count++)
|
||||
ChfCondition 1, CHF_INFO ChfEnd;
|
||||
/* Push dummy conditions until an error should occur */
|
||||
for ( ; push_count <= C_STACK_SIZE; push_count++ )
|
||||
ChfCondition 1, CHF_INFO ChfEnd;
|
||||
|
||||
/* No error? Bad! */
|
||||
return (void *)EXIT_FAILURE;
|
||||
/* No error? Bad! */
|
||||
return ( void* )EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return (void *)EXIT_SUCCESS;
|
||||
return ( void* )EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#define N_THREADS 50
|
||||
|
||||
#define N_THREADS 50
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int st;
|
||||
int i;
|
||||
void *ret;
|
||||
void* ret;
|
||||
|
||||
#ifdef _REENTRANT
|
||||
pthread_t t[N_THREADS];
|
||||
pthread_t t[ N_THREADS ];
|
||||
#endif
|
||||
|
||||
puts("test05");
|
||||
puts( "test05" );
|
||||
|
||||
/* Initialization */
|
||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat",
|
||||
C_STACK_SIZE, H_STACK_SIZE, EXIT_FAILURE))
|
||||
exit(st);
|
||||
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", C_STACK_SIZE, H_STACK_SIZE, EXIT_FAILURE ) )
|
||||
exit( st );
|
||||
|
||||
#ifdef _REENTRANT
|
||||
/* Create */
|
||||
for(i=0; i<N_THREADS; i++)
|
||||
if(pthread_create(&(t[i]), NULL, task, (void *)i))
|
||||
{
|
||||
perror("pthread_create");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for ( i = 0; i < N_THREADS; i++ )
|
||||
if ( pthread_create( &( t[ i ] ), NULL, task, ( void* )i ) ) {
|
||||
perror( "pthread_create" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* Join */
|
||||
for(i=0; i<N_THREADS; i++)
|
||||
{
|
||||
if(pthread_join(t[i], &ret))
|
||||
{
|
||||
perror("pthread_join");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if((int)ret != EXIT_SUCCESS)
|
||||
exit((int)ret);
|
||||
for ( i = 0; i < N_THREADS; i++ ) {
|
||||
if ( pthread_join( t[ i ], &ret ) ) {
|
||||
perror( "pthread_join" );
|
||||
exit( EXIT_FAILURE );
|
||||
} else if ( ( int )ret != EXIT_SUCCESS )
|
||||
exit( ( int )ret );
|
||||
}
|
||||
|
||||
st = EXIT_SUCCESS;
|
||||
#else
|
||||
st = (int)task((void *)0);
|
||||
st = ( int )task( ( void* )0 );
|
||||
#endif
|
||||
|
||||
/* Exit Chf */
|
||||
ChfExit();
|
||||
exit(st);
|
||||
exit( st );
|
||||
}
|
||||
|
||||
|
|
|
@ -14,125 +14,109 @@
|
|||
#include <setjmp.h>
|
||||
|
||||
#ifdef _REENTRANT
|
||||
#include <pthread.h>
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "Chf.h"
|
||||
|
||||
#define H_STACK_SIZE 10
|
||||
#define C_STACK_SIZE 30
|
||||
#define H_STACK_SIZE 10
|
||||
#define C_STACK_SIZE 30
|
||||
|
||||
|
||||
void *task(void *arg)
|
||||
void* task( void* arg )
|
||||
{
|
||||
volatile int phase = 0;
|
||||
|
||||
ChfTry
|
||||
{
|
||||
phase = 1;
|
||||
ChfCondition 20, CHF_SUCCESS ChfEnd;
|
||||
ChfSignal();
|
||||
{
|
||||
phase = 1;
|
||||
ChfCondition 20, CHF_SUCCESS ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
phase = 2;
|
||||
ChfCondition 20, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
phase = 2;
|
||||
ChfCondition 20, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
phase = 3;
|
||||
ChfCondition 20, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
phase = 3;
|
||||
ChfCondition 20, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
phase = 4;
|
||||
ChfCondition 20, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
phase = 4;
|
||||
ChfCondition 20, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
phase = 5;
|
||||
ChfCondition 20, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
phase = 5;
|
||||
ChfCondition 20, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
/* Should not be reached */
|
||||
return (void *)EXIT_FAILURE;
|
||||
}
|
||||
/* Should not be reached */
|
||||
return ( void* )EXIT_FAILURE;
|
||||
}
|
||||
ChfCatch
|
||||
{
|
||||
/* Catched an exception; check descriptor */
|
||||
const ChfDescriptor *d = ChfGetTopCondition();
|
||||
if(d == NULL
|
||||
|| ChfGetNextDescriptor(d) != NULL
|
||||
|| ChfGetModuleId(d) != CHF_MODULE_ID
|
||||
|| ChfGetConditionCode(d) != 20)
|
||||
return (void *)EXIT_FAILURE;
|
||||
}
|
||||
{
|
||||
/* Catched an exception; check descriptor */
|
||||
const ChfDescriptor* d = ChfGetTopCondition();
|
||||
if ( d == NULL || ChfGetNextDescriptor( d ) != NULL || ChfGetModuleId( d ) != CHF_MODULE_ID || ChfGetConditionCode( d ) != 20 )
|
||||
return ( void* )EXIT_FAILURE;
|
||||
}
|
||||
ChfEndTry;
|
||||
|
||||
/* Check that the condition stack actually is empty after catch */
|
||||
ChfTry
|
||||
{
|
||||
volatile const ChfDescriptor *e = ChfGetTopCondition();
|
||||
}
|
||||
ChfTry { const volatile ChfDescriptor* e = ChfGetTopCondition(); }
|
||||
ChfCatch
|
||||
{
|
||||
const ChfDescriptor *d = ChfGetTopCondition();
|
||||
if(d == NULL
|
||||
|| ChfGetNextDescriptor(d) != NULL
|
||||
|| ChfGetModuleId(d) != CHF_SET
|
||||
|| ChfGetConditionCode(d) != CHF_F_BAD_STATE)
|
||||
return (void *)EXIT_FAILURE;
|
||||
}
|
||||
{
|
||||
const ChfDescriptor* d = ChfGetTopCondition();
|
||||
if ( d == NULL || ChfGetNextDescriptor( d ) != NULL || ChfGetModuleId( d ) != CHF_SET ||
|
||||
ChfGetConditionCode( d ) != CHF_F_BAD_STATE )
|
||||
return ( void* )EXIT_FAILURE;
|
||||
}
|
||||
ChfEndTry;
|
||||
|
||||
return (void *)EXIT_SUCCESS;
|
||||
return ( void* )EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#define N_THREADS 50
|
||||
|
||||
#define N_THREADS 50
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int st;
|
||||
int i;
|
||||
void *ret;
|
||||
void* ret;
|
||||
|
||||
#ifdef _REENTRANT
|
||||
pthread_t t[N_THREADS];
|
||||
pthread_t t[ N_THREADS ];
|
||||
#endif
|
||||
|
||||
puts("test06");
|
||||
puts( "test06" );
|
||||
|
||||
/* Initialization */
|
||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat",
|
||||
C_STACK_SIZE, H_STACK_SIZE, EXIT_FAILURE))
|
||||
exit(st);
|
||||
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", C_STACK_SIZE, H_STACK_SIZE, EXIT_FAILURE ) )
|
||||
exit( st );
|
||||
|
||||
#ifdef _REENTRANT
|
||||
/* Create */
|
||||
for(i=0; i<N_THREADS; i++)
|
||||
if(pthread_create(&(t[i]), NULL, task, (void *)i))
|
||||
{
|
||||
perror("pthread_create");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for ( i = 0; i < N_THREADS; i++ )
|
||||
if ( pthread_create( &( t[ i ] ), NULL, task, ( void* )i ) ) {
|
||||
perror( "pthread_create" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* Join */
|
||||
for(i=0; i<N_THREADS; i++)
|
||||
{
|
||||
if(pthread_join(t[i], &ret))
|
||||
{
|
||||
perror("pthread_join");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if((int)ret != EXIT_SUCCESS)
|
||||
exit((int)ret);
|
||||
for ( i = 0; i < N_THREADS; i++ ) {
|
||||
if ( pthread_join( t[ i ], &ret ) ) {
|
||||
perror( "pthread_join" );
|
||||
exit( EXIT_FAILURE );
|
||||
} else if ( ( int )ret != EXIT_SUCCESS )
|
||||
exit( ( int )ret );
|
||||
}
|
||||
|
||||
st = EXIT_SUCCESS;
|
||||
#else
|
||||
st = (int)task((void *)0);
|
||||
st = ( int )task( ( void* )0 );
|
||||
#endif
|
||||
|
||||
/* Exit Chf */
|
||||
ChfExit();
|
||||
exit(st);
|
||||
exit( st );
|
||||
}
|
||||
|
||||
|
|
|
@ -11,64 +11,55 @@
|
|||
#include <setjmp.h>
|
||||
|
||||
#ifdef _REENTRANT
|
||||
#include <pthread.h>
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "Chf.h"
|
||||
|
||||
extern ChfTable message_table[];
|
||||
extern size_t message_table_size;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int st;
|
||||
const char *msg;
|
||||
const char* msg;
|
||||
const ChfDescriptor *d, *e;
|
||||
|
||||
puts("test07");
|
||||
puts( "test07" );
|
||||
|
||||
/* Initialization */
|
||||
if(st = ChfStaticInit(argv[0], CHF_DEFAULT,
|
||||
message_table, message_table_size, 50, 10, 1))
|
||||
exit(st);
|
||||
if ( st = ChfStaticInit( argv[ 0 ], CHF_DEFAULT, message_table, message_table_size, 50, 10, 1 ) )
|
||||
exit( st );
|
||||
|
||||
/* ChfGetMessage:
|
||||
message (CHF_MODULE_ID, 1) exists, (CHF_MODULE_ID, 2) does not
|
||||
*/
|
||||
msg = ChfGetMessage(CHF_MODULE_ID, 1, "Default_1");
|
||||
if(strcmp(msg, "Set_255,Message_1")) exit(EXIT_FAILURE);
|
||||
msg = ChfGetMessage(CHF_MODULE_ID, 2, "Default_2");
|
||||
if(strcmp(msg, "Default_2")) exit(EXIT_FAILURE);
|
||||
msg = ChfGetMessage( CHF_MODULE_ID, 1, "Default_1" );
|
||||
if ( strcmp( msg, "Set_255,Message_1" ) )
|
||||
exit( EXIT_FAILURE );
|
||||
msg = ChfGetMessage( CHF_MODULE_ID, 2, "Default_2" );
|
||||
if ( strcmp( msg, "Default_2" ) )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate a condition and check descriptor; this is line 46 */
|
||||
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
||||
|
||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
||||
if(
|
||||
d->module_id != CHF_MODULE_ID
|
||||
|| d->condition_code != 3
|
||||
|| d->severity != CHF_WARNING
|
||||
|| d->line_number != 46
|
||||
|| strcmp(d->file_name, "test07.c")
|
||||
|| strcmp(d->message, "Set_255,Arg_456,Message_3")
|
||||
|| d->next != NULL
|
||||
) exit(EXIT_FAILURE);
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 3 || d->severity != CHF_WARNING || d->line_number != 46 ||
|
||||
strcmp( d->file_name, "test07.c" ) || strcmp( d->message, "Set_255,Arg_456,Message_3" ) || d->next != NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate another condition and check; this is line 60 */
|
||||
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
||||
|
||||
if((e = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
||||
if(
|
||||
e->module_id != CHF_MODULE_ID
|
||||
|| e->condition_code != 4
|
||||
|| e->severity != CHF_INFO
|
||||
|| e->line_number != 60
|
||||
|| strcmp(e->file_name, "test07.c")
|
||||
|| strcmp(e->message, "Set_255,Arg_arg,Message_4")
|
||||
|| e->next != d
|
||||
) exit(EXIT_FAILURE);
|
||||
if ( ( e = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
if ( e->module_id != CHF_MODULE_ID || e->condition_code != 4 || e->severity != CHF_INFO || e->line_number != 60 ||
|
||||
strcmp( e->file_name, "test07.c" ) || strcmp( e->message, "Set_255,Arg_arg,Message_4" ) || e->next != d )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Discard the previous condition group and create a new one */
|
||||
ChfDiscard();
|
||||
|
@ -76,28 +67,22 @@ int main(int argc, char *argv[])
|
|||
/* This is line 77 */
|
||||
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||
|
||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
||||
if(
|
||||
d->module_id != CHF_MODULE_ID
|
||||
|| d->condition_code != 5
|
||||
|| d->severity != CHF_ERROR
|
||||
|| d->line_number != 77
|
||||
|| strcmp(d->file_name, "test07.c")
|
||||
|| strcmp(d->message, "Set_255,Arg_456-789,Message_5")
|
||||
|| d->next != NULL
|
||||
) exit(EXIT_FAILURE);
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 5 || d->severity != CHF_ERROR || d->line_number != 77 ||
|
||||
strcmp( d->file_name, "test07.c" ) || strcmp( d->message, "Set_255,Arg_456-789,Message_5" ) || d->next != NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Exit Chf */
|
||||
ChfExit();
|
||||
exit(EXIT_SUCCESS);
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
ChfTable message_table[] =
|
||||
{
|
||||
{ CHF_MODULE_ID, 1, "Set_255,Message_1" },
|
||||
{ CHF_MODULE_ID, 3, "Set_255,Arg_%d,Message_3" },
|
||||
{ CHF_MODULE_ID, 4, "Set_255,Arg_%s,Message_4" },
|
||||
{ CHF_MODULE_ID, 5, "Set_255,Arg_%d-%d,Message_5" }
|
||||
ChfTable message_table[] = {
|
||||
{CHF_MODULE_ID, 1, "Set_255,Message_1" },
|
||||
{CHF_MODULE_ID, 3, "Set_255,Arg_%d,Message_3" },
|
||||
{CHF_MODULE_ID, 4, "Set_255,Arg_%s,Message_4" },
|
||||
{CHF_MODULE_ID, 5, "Set_255,Arg_%d-%d,Message_5"}
|
||||
};
|
||||
|
||||
size_t message_table_size = sizeof(message_table)/sizeof(message_table[0]);
|
||||
size_t message_table_size = sizeof( message_table ) / sizeof( message_table[ 0 ] );
|
||||
|
|
|
@ -60,16 +60,15 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Data type definitions
|
||||
All Data types must be SIGNED
|
||||
Data type definitions
|
||||
All Data types must be SIGNED
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
typedef char int1;
|
||||
typedef char int4;
|
||||
typedef char int8;
|
||||
typedef int int12;
|
||||
typedef int int16;
|
||||
typedef int int20;
|
||||
typedef int int32;
|
||||
typedef char int1;
|
||||
typedef char int4;
|
||||
typedef char int8;
|
||||
typedef int int12;
|
||||
typedef int int16;
|
||||
typedef int int20;
|
||||
typedef int int32;
|
||||
|
|
191
src/main.c
191
src/main.c
|
@ -103,8 +103,8 @@ static char rcs_id[] = "$Id: saturn.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h> /* 3.1: strcpy(), strcat() */
|
||||
#include <unistd.h> /* isatty() */
|
||||
#include <string.h> /* 3.1: strcpy(), strcat() */
|
||||
#include <unistd.h> /* isatty() */
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
|
@ -114,24 +114,22 @@ static char rcs_id[] = "$Id: saturn.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
#include "args.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
/* Chf condition codes (main program only) */
|
||||
|
||||
#define CHF_MODULE_ID MAIN_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID MAIN_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
#define MAIN_M_COPYRIGHT 501
|
||||
#define MAIN_M_LICENSE 502
|
||||
|
||||
#define MAIN_M_COPYRIGHT 501
|
||||
#define MAIN_M_LICENSE 502
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf parameters - Do not change.
|
||||
The ABNORMAL_EXIT_CODE is taken from stdlib.h (EXIT_FAILURE)
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define CONDITION_STACK_SIZE 16
|
||||
#define HANDLER_STACK_SIZE 8
|
||||
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
||||
#define CONDITION_STACK_SIZE 16
|
||||
#define HANDLER_STACK_SIZE 8
|
||||
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
||||
|
||||
/* Conditional prefix and mandatory suffix to make a message catalog
|
||||
name from argv[0]
|
||||
|
@ -139,31 +137,27 @@ static char rcs_id[] = "$Id: saturn.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
static const char cat_prefix[] = "./";
|
||||
static const char cat_suffix[] = ".cat";
|
||||
|
||||
#define CAT_PREFIX_LEN (sizeof(cat_prefix)+1)
|
||||
#define CAT_SUFFIX_LEN (sizeof(cat_suffix)+1)
|
||||
#define CAT_PREFIX_LEN ( sizeof( cat_prefix ) + 1 )
|
||||
#define CAT_SUFFIX_LEN ( sizeof( cat_suffix ) + 1 )
|
||||
|
||||
|
||||
static void adjust_setlocale(void)
|
||||
static void adjust_setlocale( void )
|
||||
{
|
||||
fprintf(stderr,
|
||||
"saturn-W-locale probably bad; reverting to C locale\n");
|
||||
fprintf( stderr, "saturn-W-locale probably bad; reverting to C locale\n" );
|
||||
|
||||
putenv("LC_ALL=C");
|
||||
putenv("LC_COLLATE=C");
|
||||
putenv("LC_CTYPE=C");
|
||||
putenv("LC_MESSAGES=C");
|
||||
putenv("LC_MONETARY=C");
|
||||
putenv("LC_NUMERIC=C");
|
||||
putenv("LC_TIME=C");
|
||||
putenv("LANG=C");
|
||||
putenv( "LC_ALL=C" );
|
||||
putenv( "LC_COLLATE=C" );
|
||||
putenv( "LC_CTYPE=C" );
|
||||
putenv( "LC_MESSAGES=C" );
|
||||
putenv( "LC_MONETARY=C" );
|
||||
putenv( "LC_NUMERIC=C" );
|
||||
putenv( "LC_TIME=C" );
|
||||
putenv( "LANG=C" );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : main
|
||||
|
@ -182,98 +176,89 @@ static void adjust_setlocale(void)
|
|||
- made Chf initialization more robust with respect to bad locales
|
||||
|
||||
.- */
|
||||
int main(int argc, char *argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
char *cat_name;
|
||||
char* cat_name;
|
||||
int st;
|
||||
int retry = 0;
|
||||
|
||||
if((cat_name = malloc(strlen(argv[0])+CAT_PREFIX_LEN+CAT_SUFFIX_LEN+1))
|
||||
== NULL)
|
||||
{
|
||||
fprintf(stderr, "saturn-E-cat_name initialization failed\n");
|
||||
exit(ABNORMAL_EXIT_CODE);
|
||||
if ( ( cat_name = malloc( strlen( argv[ 0 ] ) + CAT_PREFIX_LEN + CAT_SUFFIX_LEN + 1 ) ) == NULL ) {
|
||||
fprintf( stderr, "saturn-E-cat_name initialization failed\n" );
|
||||
exit( ABNORMAL_EXIT_CODE );
|
||||
}
|
||||
|
||||
/* Generate catalog name, without optional prefix */
|
||||
strcpy(cat_name, argv[0]);
|
||||
strcat(cat_name, cat_suffix);
|
||||
strcpy( cat_name, argv[ 0 ] );
|
||||
strcat( cat_name, cat_suffix );
|
||||
|
||||
/* 3.15: Retry the initialization steps below two times; before trying
|
||||
the second time, adjust the setlocale() environment variables
|
||||
with adjust_setlocale()
|
||||
*/
|
||||
while(retry < 2)
|
||||
{
|
||||
/* Chf initialization with msgcat subsystem; notice that on
|
||||
some systems (e.g. Digital UNIX) catopen() can succeed even
|
||||
if it was not able to open the right message catalog;
|
||||
better try it now.
|
||||
*/
|
||||
if((st = ChfMsgcatInit(
|
||||
argv[0], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||
)) != CHF_S_OK
|
||||
||
|
||||
ChfGetMessage(CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL) == NULL)
|
||||
fprintf(stderr,
|
||||
"saturn-E-Primary Chf initialization failed (%d)\n", st);
|
||||
while ( retry < 2 ) {
|
||||
/* Chf initialization with msgcat subsystem; notice that on
|
||||
some systems (e.g. Digital UNIX) catopen() can succeed even
|
||||
if it was not able to open the right message catalog;
|
||||
better try it now.
|
||||
*/
|
||||
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ||
|
||||
ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL ) == NULL )
|
||||
fprintf( stderr, "saturn-E-Primary Chf initialization failed (%d)\n", st );
|
||||
|
||||
else
|
||||
break;
|
||||
else
|
||||
break;
|
||||
|
||||
/* Bring down Chf before initializing it again */
|
||||
if(st == CHF_S_OK) ChfExit();
|
||||
/* Bring down Chf before initializing it again */
|
||||
if ( st == CHF_S_OK )
|
||||
ChfExit();
|
||||
|
||||
/* Try alternate message catalog name (with prefix) */
|
||||
strcpy(cat_name, cat_prefix);
|
||||
strcat(cat_name, argv[0]);
|
||||
strcat(cat_name, cat_suffix);
|
||||
/* Try alternate message catalog name (with prefix) */
|
||||
strcpy( cat_name, cat_prefix );
|
||||
strcat( cat_name, argv[ 0 ] );
|
||||
strcat( cat_name, cat_suffix );
|
||||
|
||||
if((st = ChfMsgcatInit(
|
||||
argv[0], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||
)) != CHF_S_OK
|
||||
||
|
||||
ChfGetMessage(CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL) == NULL)
|
||||
fprintf(stderr,
|
||||
"saturn-E-Alternate Chf initialization failed (%d)\n",
|
||||
st);
|
||||
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ||
|
||||
ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL ) == NULL )
|
||||
fprintf( stderr, "saturn-E-Alternate Chf initialization failed (%d)\n", st );
|
||||
|
||||
else
|
||||
break;
|
||||
else
|
||||
break;
|
||||
|
||||
/* Bring down Chf before initializing it again */
|
||||
if(st == CHF_S_OK) ChfExit();
|
||||
/* Bring down Chf before initializing it again */
|
||||
if ( st == CHF_S_OK )
|
||||
ChfExit();
|
||||
|
||||
/* Attempt to adjust setlocale() environment variables */
|
||||
if(retry++ == 0) adjust_setlocale();
|
||||
/* Attempt to adjust setlocale() environment variables */
|
||||
if ( retry++ == 0 )
|
||||
adjust_setlocale();
|
||||
}
|
||||
|
||||
if(retry == 2)
|
||||
{
|
||||
fprintf(stderr, "saturn-F-Application aborted\n");
|
||||
exit(ABNORMAL_EXIT_CODE);
|
||||
if ( retry == 2 ) {
|
||||
fprintf( stderr, "saturn-F-Application aborted\n" );
|
||||
exit( ABNORMAL_EXIT_CODE );
|
||||
}
|
||||
|
||||
/* cat_name no longer needed */
|
||||
free(cat_name);
|
||||
free( cat_name );
|
||||
|
||||
/* 3.9: Print out MAIN_M_COPYRIGHT and MAIN_M_LICENSE on stdout now */
|
||||
fprintf(stdout, ChfGetMessage(CHF_MODULE_ID, MAIN_M_COPYRIGHT, ""),
|
||||
"$Revision: 4.1 $");
|
||||
fprintf(stdout, ChfGetMessage(CHF_MODULE_ID, MAIN_M_LICENSE, ""));
|
||||
fprintf( stdout, ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, "" ), "$Revision: 4.1 $" );
|
||||
fprintf( stdout, ChfGetMessage( CHF_MODULE_ID, MAIN_M_LICENSE, "" ) );
|
||||
|
||||
/* Initialize GUI and associated lcd display emulation module */
|
||||
InitializeGui(argc, argv);
|
||||
InitializeGui( argc, argv );
|
||||
|
||||
/* Initialize serial port emulation.
|
||||
This function returns the name of the slave side of the pty;
|
||||
|
@ -281,30 +266,28 @@ int main(int argc, char *argv[])
|
|||
a condition containing the same information and displays the pty name
|
||||
on the main emulator's window.
|
||||
*/
|
||||
(void)SerialInit();
|
||||
( void )SerialInit();
|
||||
|
||||
/* Initialize emulator proper */
|
||||
EmulatorInit();
|
||||
|
||||
/* 3.15: Repeat copyright message on GUI if stdout is not a tty */
|
||||
if(! isatty(fileno(stdout)))
|
||||
{
|
||||
ChfCondition MAIN_M_LICENSE, CHF_INFO ChfEnd;
|
||||
ChfCondition MAIN_M_COPYRIGHT, CHF_INFO, "$Revision: 4.1 $" ChfEnd;
|
||||
if ( !isatty( fileno( stdout ) ) ) {
|
||||
ChfCondition MAIN_M_LICENSE, CHF_INFO ChfEnd;
|
||||
ChfCondition MAIN_M_COPYRIGHT, CHF_INFO, "$Revision: 4.1 $" ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
if(args.monitor)
|
||||
{
|
||||
/* Invoke Monitor */
|
||||
void Monitor(void);
|
||||
Monitor();
|
||||
if ( args.monitor ) {
|
||||
/* Invoke Monitor */
|
||||
void Monitor( void );
|
||||
Monitor();
|
||||
}
|
||||
|
||||
else
|
||||
/* Call Emulator directly */
|
||||
Emulator();
|
||||
/* Call Emulator directly */
|
||||
Emulator();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
1493
src/modules.c
1493
src/modules.c
File diff suppressed because it is too large
Load diff
520
src/modules.h
520
src/modules.h
|
@ -117,145 +117,135 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Data type definitions - require config.h, machdep.h, cpu.h
|
||||
Data type definitions - require config.h, machdep.h, cpu.h
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define N_MOD 6
|
||||
#define N_PAGE_TABLE_ENTRIES 16384
|
||||
#define N_ROM_SIZE 512*1024*2
|
||||
#define N_RAM_SIZE 128*1024*2
|
||||
#define N_FLASH_SIZE_49 2048*1024*2 /* 3.2 */
|
||||
#define N_RAM_SIZE_49 512*1024*2 /* 3.2 */
|
||||
#define N_MOD 6
|
||||
#define N_PAGE_TABLE_ENTRIES 16384
|
||||
#define N_ROM_SIZE 512 * 1024 * 2
|
||||
#define N_RAM_SIZE 128 * 1024 * 2
|
||||
#define N_FLASH_SIZE_49 2048 * 1024 * 2 /* 3.2 */
|
||||
#define N_RAM_SIZE_49 512 * 1024 * 2 /* 3.2 */
|
||||
|
||||
/* 2.4: Port_1 (CE2) size */
|
||||
#define N_PORT_1_SIZE 128*1024*2
|
||||
#define N_PORT_1_SIZE 128 * 1024 * 2
|
||||
/* 2.4: Port_2 (NCE3) size */
|
||||
#define N_PORT_2_SIZE N_PORT_2_BANK*128*1024*2
|
||||
#define N_PORT_2_SIZE N_PORT_2_BANK * 128 * 1024 * 2
|
||||
|
||||
#define N_HDW_SIZE 256
|
||||
#define N_HDW_SIZE 256
|
||||
|
||||
#define MOD_MAP_CHECK_OB_SIZE 128
|
||||
#define MOD_MAP_TABLE_OB_SIZE 512
|
||||
#define MOD_MAP_CHECK_OB_SIZE 128
|
||||
#define MOD_MAP_TABLE_OB_SIZE 512
|
||||
|
||||
/* 2.7: Number of entries in module config cache */
|
||||
#define N_MOD_CACHE_ENTRIES 8
|
||||
|
||||
#define MOD_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
#define N_MOD_CACHE_ENTRIES 8
|
||||
|
||||
#define MOD_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macros
|
||||
Macros
|
||||
|
||||
ModAddress returns the base address of a page, given its number (Address)
|
||||
ModOffset returns the page offset of an address (int)
|
||||
ModPage returns the page number of an address (Address)
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define ModAddress(page) ((Address)(page) << 6)
|
||||
#define ModPage(address) ((int)(((address) & 0xFFFC0) >> 6))
|
||||
#define ModOffset(address) ((address) & 0x0003F)
|
||||
#define ModAddress( page ) ( ( Address )( page ) << 6 )
|
||||
#define ModPage( address ) ( ( int )( ( ( address ) & 0xFFFC0 ) >> 6 ) )
|
||||
#define ModOffset( address ) ( ( address ) & 0x0003F )
|
||||
|
||||
|
||||
/*
|
||||
ModDescription
|
||||
/*
|
||||
ModDescription
|
||||
|
||||
This const array contains an entry for each peripheral module connected
|
||||
to the peripheral bus of the Saturn CPU; the entry describes the
|
||||
characteristics of the module.
|
||||
|
||||
name: the mnemonic name of the module; the Saturn CPU doesn't
|
||||
actually use this information, but it's still useful during
|
||||
debugging.
|
||||
actually use this information, but it's still useful during
|
||||
debugging.
|
||||
|
||||
id: the ID of the module, returned by the C=ID instruction
|
||||
when the module is unconfigured.
|
||||
when the module is unconfigured.
|
||||
|
||||
access_prio: the access priority of the module, when the address spaces of
|
||||
more than one module overlap. Higher values correspond to
|
||||
higher priorities.
|
||||
more than one module overlap. Higher values correspond to
|
||||
higher priorities.
|
||||
|
||||
The configuration priority of the module, when there is more
|
||||
than one unconfigured module on the peripheral bus, is
|
||||
determined implicitly by the order in which the module
|
||||
descriptions into the array. The modules that come first
|
||||
in the array are configured first.
|
||||
The configuration priority of the module, when there is more
|
||||
than one unconfigured module on the peripheral bus, is
|
||||
determined implicitly by the order in which the module
|
||||
descriptions into the array. The modules that come first
|
||||
in the array are configured first.
|
||||
|
||||
init: this function is called, without arguments, during VM startup
|
||||
to initialize the device. For example, the initialization
|
||||
function for the ROM module will read the ROM image from
|
||||
disk and store them into the module status structure.
|
||||
to initialize the device. For example, the initialization
|
||||
function for the ROM module will read the ROM image from
|
||||
disk and store them into the module status structure.
|
||||
|
||||
read: this function reads a nibble from the module. It receives the
|
||||
relative address of the nibble to be read. The read function
|
||||
can return an interrupt request for the CPU.
|
||||
relative address of the nibble to be read. The read function
|
||||
can return an interrupt request for the CPU.
|
||||
|
||||
write: this function writes a nibble to the module. It receives the
|
||||
relative address and the value of the nibble to be written.
|
||||
The write function can return an interrupt request for the CPU.
|
||||
relative address and the value of the nibble to be written.
|
||||
The write function can return an interrupt request for the CPU.
|
||||
|
||||
r_config: this flag contains the configuration status of the module after
|
||||
a bus reset. If the after-reset configuration status is
|
||||
MOD_CONFIGURED, the module can never be unconfigured.
|
||||
a bus reset. If the after-reset configuration status is
|
||||
MOD_CONFIGURED, the module can never be unconfigured.
|
||||
|
||||
r_abs_base_addr: absolute base address of the module after a bus reset.
|
||||
It should be set only if the module is at least partially
|
||||
configured automatically after a bus reset.
|
||||
It should be set only if the module is at least partially
|
||||
configured automatically after a bus reset.
|
||||
|
||||
r_size: size of the address window of the module after a bus reset.
|
||||
It should be set only if the module is at least partially
|
||||
configured automatically after a bus reset.
|
||||
It should be set only if the module is at least partially
|
||||
configured automatically after a bus reset.
|
||||
|
||||
map_flags: special map flags:
|
||||
MOD_MAP_FLAGS_ABS pass absolute addresses to module
|
||||
read/write functions
|
||||
MOD_MAP_FLAGS_ABS pass absolute addresses to module
|
||||
read/write functions
|
||||
|
||||
Notice that the current implementation requires that the index of
|
||||
the HDW registers in the mod_description table must be fixed
|
||||
and equal to MOD_HDW_INDEX... this is unfortunate.
|
||||
*/
|
||||
|
||||
typedef void (*ModInitFunction)(void);
|
||||
typedef void ( *ModInitFunction )( void );
|
||||
|
||||
typedef void (*ModSaveFunction)(void);
|
||||
typedef void ( *ModSaveFunction )( void );
|
||||
|
||||
typedef Nibble (*ModReadFunction)(Address rel_addr);
|
||||
typedef Nibble ( *ModReadFunction )( Address rel_addr );
|
||||
|
||||
typedef void (*ModWriteFunction)(Address rel_addr, Nibble data);
|
||||
typedef void ( *ModWriteFunction )( Address rel_addr, Nibble data );
|
||||
|
||||
enum ModConfig
|
||||
{
|
||||
MOD_UNCONFIGURED,
|
||||
MOD_SIZE_CONFIGURED,
|
||||
MOD_CONFIGURED
|
||||
enum ModConfig { MOD_UNCONFIGURED, MOD_SIZE_CONFIGURED, MOD_CONFIGURED };
|
||||
|
||||
struct ModDescriptionEntry {
|
||||
char* name;
|
||||
Address id;
|
||||
int access_prio;
|
||||
#define MOD_MIN_ACCESS_PRIO ( -1 )
|
||||
|
||||
ModInitFunction init;
|
||||
ModSaveFunction save;
|
||||
ModReadFunction read;
|
||||
ModWriteFunction write;
|
||||
enum ModConfig r_config;
|
||||
Address r_abs_base_addr;
|
||||
Address r_size;
|
||||
|
||||
int map_flags; /* 3.3 */
|
||||
#define MOD_MAP_FLAGS_ABS 0x1 /* Abs addresses to r/w */
|
||||
};
|
||||
|
||||
struct ModDescriptionEntry
|
||||
{
|
||||
char *name;
|
||||
Address id;
|
||||
int access_prio;
|
||||
#define MOD_MIN_ACCESS_PRIO (-1)
|
||||
#define MOD_HDW_INDEX 1
|
||||
typedef const struct ModDescriptionEntry ModDescription[ N_MOD ];
|
||||
|
||||
ModInitFunction init;
|
||||
ModSaveFunction save;
|
||||
ModReadFunction read;
|
||||
ModWriteFunction write;
|
||||
enum ModConfig r_config;
|
||||
Address r_abs_base_addr;
|
||||
Address r_size;
|
||||
|
||||
int map_flags; /* 3.3 */
|
||||
#define MOD_MAP_FLAGS_ABS 0x1 /* Abs addresses to r/w */
|
||||
};
|
||||
|
||||
#define MOD_HDW_INDEX 1
|
||||
typedef const struct ModDescriptionEntry ModDescription[N_MOD];
|
||||
|
||||
|
||||
/*
|
||||
ModMapInfo
|
||||
/*
|
||||
ModMapInfo
|
||||
|
||||
This array contains an entry for each peripheral module connected
|
||||
to the peripheral bus of the Saturn CPU; the entry describes the
|
||||
|
@ -264,41 +254,39 @@ typedef const struct ModDescriptionEntry ModDescription[N_MOD];
|
|||
config: contains the current configuration status of the module.
|
||||
|
||||
abs_base_addr: contains the current absolute base address of the module.
|
||||
It's valid only if the module is currently configured.
|
||||
It's valid only if the module is currently configured.
|
||||
|
||||
size: contains the current size of the address window of the module.
|
||||
It's valid only if the module is currently configured.
|
||||
It's valid only if the module is currently configured.
|
||||
*/
|
||||
struct ModMapInfoEntry
|
||||
{
|
||||
enum ModConfig config;
|
||||
Address abs_base_addr;
|
||||
Address size;
|
||||
struct ModMapInfoEntry {
|
||||
enum ModConfig config;
|
||||
Address abs_base_addr;
|
||||
Address size;
|
||||
};
|
||||
|
||||
typedef struct ModMapInfoEntry ModMapInfo[N_MOD];
|
||||
typedef struct ModMapInfoEntry ModMapInfo[ N_MOD ];
|
||||
|
||||
|
||||
/*
|
||||
ModPageTable
|
||||
/*
|
||||
ModPageTable
|
||||
|
||||
This array contains an entry (of type ModPageTableEntry) for each 'page'
|
||||
(of size #40 nibbles) of the Saturn CPU physical address space. For
|
||||
each page, the following information is stored:
|
||||
|
||||
index: the index of the module that responds to the address range of
|
||||
the page in the ModDescription table.The special value
|
||||
MOD_NO_MOD_INDEX indicates that no module responds to the
|
||||
address range.
|
||||
the page in the ModDescription table.The special value
|
||||
MOD_NO_MOD_INDEX indicates that no module responds to the
|
||||
address range.
|
||||
|
||||
rel_base_addr: the relative base address of the page in the address
|
||||
space of the module that responds to the address range of
|
||||
the page, if any.
|
||||
space of the module that responds to the address range of
|
||||
the page, if any.
|
||||
|
||||
read, write: the read/write functions of the module that responds to the
|
||||
address range of the page, if any.
|
||||
address range of the page, if any.
|
||||
|
||||
Relative address calculation for module access
|
||||
Relative address calculation for module access
|
||||
|
||||
The Saturn Physical Address (SPA) is divided into two portions:
|
||||
|
||||
|
@ -313,20 +301,18 @@ typedef struct ModMapInfoEntry ModMapInfo[N_MOD];
|
|||
The relative address (RA) therefore will be RA = RBA | OFF; then, the
|
||||
appropriate module access function, found again in ModPageTable[PI],
|
||||
is called.
|
||||
|
||||
*/
|
||||
struct ModPageTableEntry
|
||||
{
|
||||
int index;
|
||||
#define MOD_NO_MOD_INDEX (-1)
|
||||
|
||||
Address rel_base_addr;
|
||||
ModReadFunction read;
|
||||
ModWriteFunction write;
|
||||
*/
|
||||
struct ModPageTableEntry {
|
||||
int index;
|
||||
#define MOD_NO_MOD_INDEX ( -1 )
|
||||
|
||||
Address rel_base_addr;
|
||||
ModReadFunction read;
|
||||
ModWriteFunction write;
|
||||
};
|
||||
|
||||
typedef struct ModPageTableEntry ModPageTable[N_PAGE_TABLE_ENTRIES];
|
||||
|
||||
typedef struct ModPageTableEntry ModPageTable[ N_PAGE_TABLE_ENTRIES ];
|
||||
|
||||
/* struct ModCache (2.7)
|
||||
|
||||
|
@ -359,58 +345,53 @@ typedef struct ModPageTableEntry ModPageTable[N_PAGE_TABLE_ENTRIES];
|
|||
|
||||
The .link field links all cached struct ModMap together.
|
||||
*/
|
||||
struct ModCacheTableEntry
|
||||
{
|
||||
struct ModCacheTableEntry {
|
||||
Address tag;
|
||||
struct ModMap *map_ptr;
|
||||
struct ModMap* map_ptr;
|
||||
};
|
||||
|
||||
struct ModCache
|
||||
{
|
||||
struct ModCacheTableEntry config[N_MOD_CACHE_ENTRIES];
|
||||
struct ModCache {
|
||||
struct ModCacheTableEntry config[ N_MOD_CACHE_ENTRIES ];
|
||||
int victim;
|
||||
|
||||
struct ModMap *(unconfig[N_MOD]);
|
||||
struct ModMap*( unconfig[ N_MOD ] );
|
||||
|
||||
int config_point;
|
||||
int ref_count;
|
||||
|
||||
struct ModMap *link;
|
||||
struct ModMap* link;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
struct ModMap
|
||||
/*
|
||||
struct ModMap
|
||||
|
||||
This structure contains all the mapping information about the peripheral
|
||||
modules of the Saturn CPU. Its components are:
|
||||
|
||||
map_info: this array describes the dynamic mapping information of
|
||||
each module connected to the Saturn peripheral bus.
|
||||
each module connected to the Saturn peripheral bus.
|
||||
|
||||
page_table: this array describes the current layout of the address space
|
||||
of the Saturn CPU.
|
||||
of the Saturn CPU.
|
||||
|
||||
cache (2.7): this structure holds caching information used to speed up
|
||||
module config/unconfig instructions
|
||||
module config/unconfig instructions
|
||||
|
||||
*/
|
||||
struct ModMap
|
||||
{
|
||||
ModMapInfo map_info;
|
||||
ModPageTable page_table;
|
||||
struct ModCache cache;
|
||||
struct ModMap {
|
||||
ModMapInfo map_info;
|
||||
ModPageTable page_table;
|
||||
struct ModCache cache;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
struct ModStatus
|
||||
struct ModStatus
|
||||
|
||||
This structure contains the actual status of all peripheral modules of the
|
||||
Saturn CPU. The status of all modules is centralized to allow any device
|
||||
to easily access the status of other devices.
|
||||
|
||||
struct ModHdw
|
||||
struct ModHdw
|
||||
|
||||
This substructure contains the status of all peripheral devices controlled
|
||||
by the hdw module.
|
||||
|
@ -427,190 +408,179 @@ struct ModMap
|
|||
ModStatus structure except .hdw): contains the storage areas for
|
||||
ROM and RAM in configuration 'xx', and is private to the
|
||||
configuration-specific ROM/RAM emulation module.
|
||||
|
||||
|
||||
*/
|
||||
struct ModHdw48Accel
|
||||
{
|
||||
XAddress bs_address; /* Bank Switcher ext. address */
|
||||
struct ModHdw48Accel {
|
||||
XAddress bs_address; /* Bank Switcher ext. address */
|
||||
};
|
||||
|
||||
struct ModHdw49Accel
|
||||
{
|
||||
XAddress view[2]; /* Base of Flash views */
|
||||
struct ModHdw49Accel {
|
||||
XAddress view[ 2 ]; /* Base of Flash views */
|
||||
};
|
||||
|
||||
struct ModHdw
|
||||
{
|
||||
Nibble hdw[N_HDW_SIZE]; /* HDW registers */
|
||||
struct ModHdw {
|
||||
Nibble hdw[ N_HDW_SIZE ]; /* HDW registers */
|
||||
|
||||
/* LCD driver */
|
||||
Address lcd_base_addr; /* LCD driver base address */
|
||||
int lcd_on; /* LCD driver enable flag */
|
||||
int lcd_contrast; /* LCD contrast value */
|
||||
int lcd_vlc; /* LCD vertical line count */
|
||||
int lcd_offset; /* LCD horizontal offset */
|
||||
int lcd_line_offset; /* LCD line offset */
|
||||
Address lcd_menu_addr; /* LCD menu base address */
|
||||
int lcd_ann; /* LCD annunciators status */
|
||||
/* LCD driver */
|
||||
Address lcd_base_addr; /* LCD driver base address */
|
||||
int lcd_on; /* LCD driver enable flag */
|
||||
int lcd_contrast; /* LCD contrast value */
|
||||
int lcd_vlc; /* LCD vertical line count */
|
||||
int lcd_offset; /* LCD horizontal offset */
|
||||
int lcd_line_offset; /* LCD line offset */
|
||||
Address lcd_menu_addr; /* LCD menu base address */
|
||||
int lcd_ann; /* LCD annunciators status */
|
||||
|
||||
/* Timers */
|
||||
Nibble t1_ctrl; /* Timer 1 control */
|
||||
#define T1_CTRL_EXTRA 0x01
|
||||
#define T1_CTRL_INT 0x02
|
||||
#define T1_CTRL_WAKE 0x04
|
||||
#define T1_CTRL_SREQ 0x08
|
||||
/* Timers */
|
||||
Nibble t1_ctrl; /* Timer 1 control */
|
||||
#define T1_CTRL_EXTRA 0x01
|
||||
#define T1_CTRL_INT 0x02
|
||||
#define T1_CTRL_WAKE 0x04
|
||||
#define T1_CTRL_SREQ 0x08
|
||||
|
||||
Nibble t2_ctrl; /* Timer 2 control */
|
||||
#define T2_CTRL_TRUN 0x01
|
||||
#define T2_CTRL_INT 0x02
|
||||
#define T2_CTRL_WAKE 0x04
|
||||
#define T2_CTRL_SREQ 0x08
|
||||
Nibble t2_ctrl; /* Timer 2 control */
|
||||
#define T2_CTRL_TRUN 0x01
|
||||
#define T2_CTRL_INT 0x02
|
||||
#define T2_CTRL_WAKE 0x04
|
||||
#define T2_CTRL_SREQ 0x08
|
||||
|
||||
Nibble t1_val; /* Timer 1 value */
|
||||
int32 t2_val; /* Timer 2 value */
|
||||
Nibble t1_val; /* Timer 1 value */
|
||||
int32 t2_val; /* Timer 2 value */
|
||||
|
||||
/* 2.4: New member required to support Port emulation */
|
||||
Nibble card_status; /* Card status (hdw register 0x0F) */
|
||||
#define NCE3_CARD_PRESENT 0x01
|
||||
#define CE2_CARD_PRESENT 0x02
|
||||
#define NCE3_CARD_WE 0x04
|
||||
#define CE2_CARD_WE 0x08
|
||||
/* 2.4: New member required to support Port emulation */
|
||||
Nibble card_status; /* Card status (hdw register 0x0F) */
|
||||
#define NCE3_CARD_PRESENT 0x01
|
||||
#define CE2_CARD_PRESENT 0x02
|
||||
#define NCE3_CARD_WE 0x04
|
||||
#define CE2_CARD_WE 0x08
|
||||
|
||||
/* 2.4: Hw configuration-specific members used as accelerators;
|
||||
accel_valid is non-zero if the accelerators are valid
|
||||
*/
|
||||
int accel_valid;
|
||||
/* 2.4: Hw configuration-specific members used as accelerators;
|
||||
accel_valid is non-zero if the accelerators are valid
|
||||
*/
|
||||
int accel_valid;
|
||||
|
||||
union
|
||||
{
|
||||
struct ModHdw48Accel a48;
|
||||
struct ModHdw49Accel a49;
|
||||
} accel;
|
||||
union {
|
||||
struct ModHdw48Accel a48;
|
||||
struct ModHdw49Accel a49;
|
||||
} accel;
|
||||
|
||||
/* 2.5: Serial port buffer registers */
|
||||
int8 serial_rbr;
|
||||
int8 serial_tbr;
|
||||
/* 2.5: Serial port buffer registers */
|
||||
int8 serial_rbr;
|
||||
int8 serial_tbr;
|
||||
|
||||
/* Misc */
|
||||
int16 crc; /* CRC */
|
||||
/* Misc */
|
||||
int16 crc; /* CRC */
|
||||
};
|
||||
|
||||
struct ModStatus
|
||||
{
|
||||
struct ModHdw hdw; /* HDW status */
|
||||
struct ModStatus {
|
||||
struct ModHdw hdw; /* HDW status */
|
||||
};
|
||||
|
||||
struct ModStatus_48
|
||||
{
|
||||
Nibble rom[N_ROM_SIZE]; /* Internal ROM */
|
||||
Nibble ram[N_RAM_SIZE]; /* Internal RAM */
|
||||
Nibble port_1[N_PORT_1_SIZE]; /* 2.4: Port_1 (CE2) storage */
|
||||
struct ModStatus_48 {
|
||||
Nibble rom[ N_ROM_SIZE ]; /* Internal ROM */
|
||||
Nibble ram[ N_RAM_SIZE ]; /* Internal RAM */
|
||||
Nibble port_1[ N_PORT_1_SIZE ]; /* 2.4: Port_1 (CE2) storage */
|
||||
|
||||
/* 2.4: Port_2 (NCE3) storage; only needed if N_PORT_2_BANK is defined */
|
||||
/* 2.4: Port_2 (NCE3) storage; only needed if N_PORT_2_BANK is defined */
|
||||
#ifdef N_PORT_2_BANK
|
||||
Nibble port_2[N_PORT_2_SIZE];
|
||||
Nibble port_2[ N_PORT_2_SIZE ];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ModStatus_49
|
||||
{
|
||||
Nibble flash[N_FLASH_SIZE_49]; /* Internal Flash ROM */
|
||||
Nibble ram[N_RAM_SIZE_49]; /* Internal RAM */
|
||||
Nibble *ce2, *nce3; /* ERAM bases */
|
||||
struct ModStatus_49 {
|
||||
Nibble flash[ N_FLASH_SIZE_49 ]; /* Internal Flash ROM */
|
||||
Nibble ram[ N_RAM_SIZE_49 ]; /* Internal RAM */
|
||||
Nibble *ce2, *nce3; /* ERAM bases */
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Global variables
|
||||
Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
extern struct ModStatus mod_status;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf condition codes
|
||||
Chf condition codes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define MOD_I_CALLED 101 /* Function %s called */
|
||||
#define MOD_I_INITIALIZING 102 /* Initializing module %s */
|
||||
#define MOD_I_RESETTING 103 /* Resetting module %s */
|
||||
#define MOD_I_GET_ID 106 /* ModGetID returning %x */
|
||||
#define MOD_I_CONFIG 107 /* ModConfig %s %x %x completed */
|
||||
#define MOD_I_UNCONFIG 108 /* ModUnconfig %s %x %x completed */
|
||||
#define MOD_I_SAVING 109 /* Saving status of module %s */
|
||||
#define MOD_I_NOT_IMPLEMENTED 110 /* Function %s not implemented */
|
||||
#define MOD_I_REVISION 111 /* Modules revision: %s */
|
||||
#define MOD_I_BS_ADDRESS 112 /* 2.4: Bank Switcher address: %x */
|
||||
#define MOD_I_PORT_1_WP 113 /* 2.4: Port 1 is write protected */
|
||||
#define MOD_I_PORT_2_WP 114 /* 2.4: Port 2 is write protected */
|
||||
#define MOD_I_PERF_CTR 115 /* 2.7: Value of PerfCtr %s is %d */
|
||||
#define MOD_I_CACHED_UNCONFIG 116 /* 2.7: Cached ModUnconfig completed */
|
||||
#define MOD_I_CACHED_CONFIG 117 /* 2.7: Cached ModConfig %x comp. */
|
||||
#define MOD_I_UNCONFIG_L_HIT 118 /* 2.7: Late unconfig hit */
|
||||
#define MOD_I_UNCONFIG_L_MISS 119 /* 2.7: Late unconfig miss */
|
||||
#define MOD_W_BAD_CONFIG 202 /* Bad ModConfig %x ignored */
|
||||
#define MOD_W_BAD_UNCONFIG 203 /* Bad ModUnconfig %x ignored */
|
||||
#define MOD_W_HDW_WRITE 204 /* Bad HdwWrite %x, %x */
|
||||
#define MOD_W_HDW_READ 205 /* Bad HdwRead %x */
|
||||
#define MOD_W_RESETTING_ALL 206 /* Resetting all modules */
|
||||
#define MOD_W_RAM_INIT 207 /* Can't initialize internal RAM */
|
||||
#define MOD_W_HDW_INIT 208 /* Can't initialize HDW */
|
||||
#define MOD_W_BAD_KEY 209 /* 2.1: Bad key %s ignored */
|
||||
#define MOD_W_BAD_OUT_BIT 210 /* 2.1: Bad out_bit %x ignored */
|
||||
#define MOD_W_PORT_1_INIT 211 /* 2.4: Can't initialize Port 1 */
|
||||
#define MOD_W_PORT_2_INIT 212 /* 2.4: Can't initialize Port 2 */
|
||||
#define MOD_W_NO_VICTIM 213 /* 2.7: No cache victim; flush/retry */
|
||||
#define MOD_E_BAD_READ 301 /* Read unmapped addr %x */
|
||||
#define MOD_E_BAD_WRITE 302 /* Write unmapped addr %x datum %x */
|
||||
#define MOD_E_ROM_WRITE 303 /* Write into ROM addr %x datum %x */
|
||||
#define MOD_E_RAM_SAVE 304 /* Can't save internal RAM status */
|
||||
#define MOD_E_HDW_SAVE 305 /* Can't save HDW status */
|
||||
#define MOD_E_PORT_1_SAVE 306 /* 2.4: Can't save Port 1 status */
|
||||
#define MOD_E_CE1_WRITE 307 /* 2.4: Ce1Write addr %x datum %x */
|
||||
#define MOD_E_PORT_2_SAVE 308 /* 2.4: Can't save Port 2 status */
|
||||
#define MOD_E_NCE3_READ 309 /* 2.4: Read from NCE3 addr %x */
|
||||
#define MOD_E_NCE3_WRITE 310 /* 2.4: Wr. to NCE3 addr %x datum %x */
|
||||
#define MOD_E_NO_MATCH 311 /* 3.2: Hw desription %s not found */
|
||||
#define MOD_E_ROM_SAVE 312 /* 3.3: Can't save Flash ROM */
|
||||
#define MOD_F_MAP_SAVE 401 /* Can't save mod_map information */
|
||||
#define MOD_F_ROM_INIT 402 /* Can't initialize internal ROM */
|
||||
#define MOD_F_MAP_ALLOC 403 /* Dynamic map allocation failed */
|
||||
#define MOD_F_BAD_ALLOC_C 404 /* 2.7: Bad alloc_c %d aft FlushCache*/
|
||||
#define MOD_F_CHAIN_CORRUPTED 405 /* 2.7: ModMap chain corrupted */
|
||||
#define MOD_F_NO_VICTIM 406 /* 2.7: No cache victim after flush */
|
||||
#define MOD_F_MOD_STATUS_ALLOC 407 /* 3.2: ModStatus_xx alloc failed %d */
|
||||
#define MOD_F_NO_DESCRIPTION 408 /* 3.2: No module description */
|
||||
#define MOD_M_NOT_MAPPED 501 /* Address %x not mapped */
|
||||
#define MOD_M_MAPPED 502 /* Address %x mapped to %s:%x */
|
||||
#define MOD_M_MAP_TABLE_TITLE 503 /* */
|
||||
#define MOD_M_MAP_TABLE_ROW 504 /* %s %x %x %s */
|
||||
#define MOD_M_MAP_CONFIGURED 505 /* Configured */
|
||||
#define MOD_M_MAP_SZ_CONFIGURED 506 /* Size configured */
|
||||
#define MOD_M_MAP_UNCONFIGURED 507 /* Unconfigured */
|
||||
|
||||
|
||||
#define MOD_I_CALLED 101 /* Function %s called */
|
||||
#define MOD_I_INITIALIZING 102 /* Initializing module %s */
|
||||
#define MOD_I_RESETTING 103 /* Resetting module %s */
|
||||
#define MOD_I_GET_ID 106 /* ModGetID returning %x */
|
||||
#define MOD_I_CONFIG 107 /* ModConfig %s %x %x completed */
|
||||
#define MOD_I_UNCONFIG 108 /* ModUnconfig %s %x %x completed */
|
||||
#define MOD_I_SAVING 109 /* Saving status of module %s */
|
||||
#define MOD_I_NOT_IMPLEMENTED 110 /* Function %s not implemented */
|
||||
#define MOD_I_REVISION 111 /* Modules revision: %s */
|
||||
#define MOD_I_BS_ADDRESS 112 /* 2.4: Bank Switcher address: %x */
|
||||
#define MOD_I_PORT_1_WP 113 /* 2.4: Port 1 is write protected */
|
||||
#define MOD_I_PORT_2_WP 114 /* 2.4: Port 2 is write protected */
|
||||
#define MOD_I_PERF_CTR 115 /* 2.7: Value of PerfCtr %s is %d */
|
||||
#define MOD_I_CACHED_UNCONFIG 116 /* 2.7: Cached ModUnconfig completed */
|
||||
#define MOD_I_CACHED_CONFIG 117 /* 2.7: Cached ModConfig %x comp. */
|
||||
#define MOD_I_UNCONFIG_L_HIT 118 /* 2.7: Late unconfig hit */
|
||||
#define MOD_I_UNCONFIG_L_MISS 119 /* 2.7: Late unconfig miss */
|
||||
#define MOD_W_BAD_CONFIG 202 /* Bad ModConfig %x ignored */
|
||||
#define MOD_W_BAD_UNCONFIG 203 /* Bad ModUnconfig %x ignored */
|
||||
#define MOD_W_HDW_WRITE 204 /* Bad HdwWrite %x, %x */
|
||||
#define MOD_W_HDW_READ 205 /* Bad HdwRead %x */
|
||||
#define MOD_W_RESETTING_ALL 206 /* Resetting all modules */
|
||||
#define MOD_W_RAM_INIT 207 /* Can't initialize internal RAM */
|
||||
#define MOD_W_HDW_INIT 208 /* Can't initialize HDW */
|
||||
#define MOD_W_BAD_KEY 209 /* 2.1: Bad key %s ignored */
|
||||
#define MOD_W_BAD_OUT_BIT 210 /* 2.1: Bad out_bit %x ignored */
|
||||
#define MOD_W_PORT_1_INIT 211 /* 2.4: Can't initialize Port 1 */
|
||||
#define MOD_W_PORT_2_INIT 212 /* 2.4: Can't initialize Port 2 */
|
||||
#define MOD_W_NO_VICTIM 213 /* 2.7: No cache victim; flush/retry */
|
||||
#define MOD_E_BAD_READ 301 /* Read unmapped addr %x */
|
||||
#define MOD_E_BAD_WRITE 302 /* Write unmapped addr %x datum %x */
|
||||
#define MOD_E_ROM_WRITE 303 /* Write into ROM addr %x datum %x */
|
||||
#define MOD_E_RAM_SAVE 304 /* Can't save internal RAM status */
|
||||
#define MOD_E_HDW_SAVE 305 /* Can't save HDW status */
|
||||
#define MOD_E_PORT_1_SAVE 306 /* 2.4: Can't save Port 1 status */
|
||||
#define MOD_E_CE1_WRITE 307 /* 2.4: Ce1Write addr %x datum %x */
|
||||
#define MOD_E_PORT_2_SAVE 308 /* 2.4: Can't save Port 2 status */
|
||||
#define MOD_E_NCE3_READ 309 /* 2.4: Read from NCE3 addr %x */
|
||||
#define MOD_E_NCE3_WRITE 310 /* 2.4: Wr. to NCE3 addr %x datum %x */
|
||||
#define MOD_E_NO_MATCH 311 /* 3.2: Hw desription %s not found */
|
||||
#define MOD_E_ROM_SAVE 312 /* 3.3: Can't save Flash ROM */
|
||||
#define MOD_F_MAP_SAVE 401 /* Can't save mod_map information */
|
||||
#define MOD_F_ROM_INIT 402 /* Can't initialize internal ROM */
|
||||
#define MOD_F_MAP_ALLOC 403 /* Dynamic map allocation failed */
|
||||
#define MOD_F_BAD_ALLOC_C 404 /* 2.7: Bad alloc_c %d aft FlushCache*/
|
||||
#define MOD_F_CHAIN_CORRUPTED 405 /* 2.7: ModMap chain corrupted */
|
||||
#define MOD_F_NO_VICTIM 406 /* 2.7: No cache victim after flush */
|
||||
#define MOD_F_MOD_STATUS_ALLOC 407 /* 3.2: ModStatus_xx alloc failed %d */
|
||||
#define MOD_F_NO_DESCRIPTION 408 /* 3.2: No module description */
|
||||
#define MOD_M_NOT_MAPPED 501 /* Address %x not mapped */
|
||||
#define MOD_M_MAPPED 502 /* Address %x mapped to %s:%x */
|
||||
#define MOD_M_MAP_TABLE_TITLE 503 /* */
|
||||
#define MOD_M_MAP_TABLE_ROW 504 /* %s %x %x %s */
|
||||
#define MOD_M_MAP_CONFIGURED 505 /* Configured */
|
||||
#define MOD_M_MAP_SZ_CONFIGURED 506 /* Size configured */
|
||||
#define MOD_M_MAP_UNCONFIGURED 507 /* Unconfigured */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Initialization */
|
||||
void ModSelectDescription(const char *hw);
|
||||
void ModRegisterDescription(ModDescription p);
|
||||
void ModInit(void);
|
||||
void ModSave(void);
|
||||
void ModReset(void);
|
||||
void ModSelectDescription( const char* hw );
|
||||
void ModRegisterDescription( ModDescription p );
|
||||
void ModInit( void );
|
||||
void ModSave( void );
|
||||
void ModReset( void );
|
||||
|
||||
/* Configuration */
|
||||
Address ModGetID(void);
|
||||
void ModConfig(Address config_info);
|
||||
void ModUnconfig(Address unconfig_info);
|
||||
Address ModGetID( void );
|
||||
void ModConfig( Address config_info );
|
||||
void ModUnconfig( Address unconfig_info );
|
||||
|
||||
/* Read/Write */
|
||||
Nibble FetchNibble(Address addr);
|
||||
Nibble ReadNibble(Address addr);
|
||||
void WriteNibble(Address addr, Nibble datum);
|
||||
Nibble FetchNibble( Address addr );
|
||||
Nibble ReadNibble( Address addr );
|
||||
void WriteNibble( Address addr, Nibble datum );
|
||||
|
||||
/* Monitor */
|
||||
void ModMapCheck(Address addr, char ob[MOD_MAP_CHECK_OB_SIZE]);
|
||||
void ModMapTable(char ob[MOD_MAP_TABLE_OB_SIZE]);
|
||||
void ModMapCheck( Address addr, char ob[ MOD_MAP_CHECK_OB_SIZE ] );
|
||||
void ModMapTable( char ob[ MOD_MAP_TABLE_OB_SIZE ] );
|
||||
|
|
334
src/monitor.c
334
src/monitor.c
|
@ -85,232 +85,229 @@ static char rcs_id[] = "$Id: monitor.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $"
|
|||
#include "args.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID CPU_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID CPU_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macro & Data type definitions
|
||||
Macro & Data type definitions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define LINE_BUFFER_SIZE 512
|
||||
#define TOK_DELIMITERS " \t\n"
|
||||
#define ADDRESS_FMT "%x"
|
||||
#define COUNT_FMT "%d"
|
||||
#define PROMPT "> "
|
||||
#define OK 0
|
||||
#define FAILED 1
|
||||
#define LINE_BUFFER_SIZE 512
|
||||
#define TOK_DELIMITERS " \t\n"
|
||||
#define ADDRESS_FMT "%x"
|
||||
#define COUNT_FMT "%d"
|
||||
#define PROMPT "> "
|
||||
#define OK 0
|
||||
#define FAILED 1
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private functions - Command line parse
|
||||
Private functions - Command line parse
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Read an Address from the command line */
|
||||
static int ReadHexAddress(Address *addr)
|
||||
static int ReadHexAddress( Address* addr )
|
||||
{
|
||||
char *p = strtok((char *)NULL, TOK_DELIMITERS);
|
||||
return (p == (char *)NULL ||
|
||||
sscanf(p, ADDRESS_FMT, addr) != 1) ? FAILED : OK;
|
||||
char* p = strtok( ( char* )NULL, TOK_DELIMITERS );
|
||||
return ( p == ( char* )NULL || sscanf( p, ADDRESS_FMT, addr ) != 1 ) ? FAILED : OK;
|
||||
}
|
||||
|
||||
/* Read a Nibble from the command line */
|
||||
static int ReadHexDatum(Nibble *n)
|
||||
static int ReadHexDatum( Nibble* n )
|
||||
{
|
||||
Address addr;
|
||||
int st;
|
||||
if((st = ReadHexAddress(&addr)) == OK) *n = (Nibble)addr;
|
||||
return st;
|
||||
Address addr;
|
||||
int st;
|
||||
if ( ( st = ReadHexAddress( &addr ) ) == OK )
|
||||
*n = ( Nibble )addr;
|
||||
return st;
|
||||
}
|
||||
|
||||
/* Read a DECIMAL count from the command line */
|
||||
static int ReadCount(int *count)
|
||||
static int ReadCount( int* count )
|
||||
{
|
||||
char *p = strtok((char *)NULL, TOK_DELIMITERS);
|
||||
return (p == (char *)NULL || sscanf(p, COUNT_FMT, count) != 1 ||
|
||||
*count <= 0) ? FAILED : OK;
|
||||
char* p = strtok( ( char* )NULL, TOK_DELIMITERS );
|
||||
return ( p == ( char* )NULL || sscanf( p, COUNT_FMT, count ) != 1 || *count <= 0 ) ? FAILED : OK;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private functions - Command execution
|
||||
Private functions - Command execution
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Run the emulator; this function exits normally only when an
|
||||
EmulatorIntRequest() is posted and satisfied
|
||||
*/
|
||||
static int run(void)
|
||||
static int run( void )
|
||||
{
|
||||
Emulator();
|
||||
return OK;
|
||||
Emulator();
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Set the debug level */
|
||||
static int debug(void)
|
||||
static int debug( void )
|
||||
{
|
||||
Address addr;
|
||||
if(ReadHexAddress(&addr)) return FAILED;
|
||||
SetDebugLevel((int)addr);
|
||||
return OK;
|
||||
Address addr;
|
||||
if ( ReadHexAddress( &addr ) )
|
||||
return FAILED;
|
||||
SetDebugLevel( ( int )addr );
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Check the mapping of an Address and print */
|
||||
static int map_check(void)
|
||||
static int map_check( void )
|
||||
{
|
||||
Address addr;
|
||||
char ob[MOD_MAP_CHECK_OB_SIZE];
|
||||
if(ReadHexAddress(&addr)) return FAILED;
|
||||
ModMapCheck(addr, ob);
|
||||
puts(ob);
|
||||
return OK;
|
||||
Address addr;
|
||||
char ob[ MOD_MAP_CHECK_OB_SIZE ];
|
||||
if ( ReadHexAddress( &addr ) )
|
||||
return FAILED;
|
||||
ModMapCheck( addr, ob );
|
||||
puts( ob );
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Print the current module map table */
|
||||
static int map(void)
|
||||
static int map( void )
|
||||
{
|
||||
char ob[MOD_MAP_TABLE_OB_SIZE];
|
||||
ModMapTable(ob);
|
||||
puts(ob);
|
||||
return OK;
|
||||
char ob[ MOD_MAP_TABLE_OB_SIZE ];
|
||||
ModMapTable( ob );
|
||||
puts( ob );
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Write nibbles into memory */
|
||||
static int w(void)
|
||||
static int w( void )
|
||||
{
|
||||
Address addr;
|
||||
Nibble n;
|
||||
if(ReadHexAddress(&addr)) return FAILED;
|
||||
while(ReadHexDatum(&n) == OK) WriteNibble(addr++, n);
|
||||
return OK;
|
||||
Address addr;
|
||||
Nibble n;
|
||||
if ( ReadHexAddress( &addr ) )
|
||||
return FAILED;
|
||||
while ( ReadHexDatum( &n ) == OK )
|
||||
WriteNibble( addr++, n );
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Read nibbles from memory */
|
||||
static int r(void)
|
||||
static int r( void )
|
||||
{
|
||||
Address addr;
|
||||
int count;
|
||||
if(ReadHexAddress(&addr)) return FAILED;
|
||||
if(ReadCount(&count)) count=1;
|
||||
Address addr;
|
||||
int count;
|
||||
if ( ReadHexAddress( &addr ) )
|
||||
return FAILED;
|
||||
if ( ReadCount( &count ) )
|
||||
count = 1;
|
||||
|
||||
while(count-->0)
|
||||
{
|
||||
printf("A_%05X\t%X\n", addr, (int)FetchNibble(addr));
|
||||
addr++;
|
||||
}
|
||||
while ( count-- > 0 ) {
|
||||
printf( "A_%05X\t%X\n", addr, ( int )FetchNibble( addr ) );
|
||||
addr++;
|
||||
}
|
||||
|
||||
return OK;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Disassemble */
|
||||
static int d(void)
|
||||
static int d( void )
|
||||
{
|
||||
Address addr;
|
||||
int count;
|
||||
char ob[DISASSEMBLE_OB_SIZE];
|
||||
Address addr;
|
||||
int count;
|
||||
char ob[ DISASSEMBLE_OB_SIZE ];
|
||||
|
||||
if(ReadHexAddress(&addr)) return FAILED;
|
||||
if(ReadCount(&count)) count=1;
|
||||
if ( ReadHexAddress( &addr ) )
|
||||
return FAILED;
|
||||
if ( ReadCount( &count ) )
|
||||
count = 1;
|
||||
|
||||
while(count-->0)
|
||||
{
|
||||
addr = Disassemble(addr, ob);
|
||||
puts(ob);
|
||||
}
|
||||
while ( count-- > 0 ) {
|
||||
addr = Disassemble( addr, ob );
|
||||
puts( ob );
|
||||
}
|
||||
|
||||
return OK;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Print CPU status */
|
||||
static int cpu(void)
|
||||
static int cpu( void )
|
||||
{
|
||||
char ob[DUMP_CPU_STATUS_OB_SIZE];
|
||||
DumpCpuStatus(ob);
|
||||
puts(ob);
|
||||
return OK;
|
||||
char ob[ DUMP_CPU_STATUS_OB_SIZE ];
|
||||
DumpCpuStatus( ob );
|
||||
puts( ob );
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Reset CPU */
|
||||
static int reset(void)
|
||||
static int reset( void )
|
||||
{
|
||||
CpuReset();
|
||||
return OK;
|
||||
CpuReset();
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Save & Exit */
|
||||
static int mon_exit(void)
|
||||
static int mon_exit( void )
|
||||
{
|
||||
ModSave();
|
||||
CpuSave();
|
||||
exit(EXIT_SUCCESS);
|
||||
return OK; /* 3.1: Keep compiler happy */
|
||||
ModSave();
|
||||
CpuSave();
|
||||
exit( EXIT_SUCCESS );
|
||||
return OK; /* 3.1: Keep compiler happy */
|
||||
}
|
||||
|
||||
/* Quit without saving */
|
||||
static int mon_quit(void)
|
||||
static int mon_quit( void )
|
||||
{
|
||||
exit(EXIT_SUCCESS);
|
||||
return OK; /* 3.1: Keep compiler happy */
|
||||
exit( EXIT_SUCCESS );
|
||||
return OK; /* 3.1: Keep compiler happy */
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Command table
|
||||
Command table
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
struct TEntry
|
||||
{
|
||||
char *name;
|
||||
char *desc;
|
||||
int (*function)(void);
|
||||
struct TEntry {
|
||||
char* name;
|
||||
char* desc;
|
||||
int ( *function )( void );
|
||||
};
|
||||
|
||||
#define TableSize(t) (sizeof(t)/sizeof(struct TEntry))
|
||||
#define TableSize( t ) ( sizeof( t ) / sizeof( struct TEntry ) )
|
||||
|
||||
/* Forward declaration for the Help funcion */
|
||||
static int Help(void);
|
||||
static int Help( void );
|
||||
|
||||
static const struct TEntry table[] =
|
||||
{
|
||||
{ "help", "Print this information", Help },
|
||||
{ "run", "Run the emulator with current CPU status", run },
|
||||
{ "?", "<addr>, Check address mapping", map_check },
|
||||
{ "r", "<addr> [count], Read nibbles from memory", r },
|
||||
{ "w", "<addr> [n]..., Write nibbles into memory", w },
|
||||
{ "d", "<addr> [count], Disassemble starting from 'addr'", d },
|
||||
{ "cpu", "Print CPU status", cpu },
|
||||
{ "map", "Print the contents of the module map table", map },
|
||||
{ "debug", "Set the debugging level", debug },
|
||||
{ "reset", "Reset CPU", reset },
|
||||
{ "exit", "Save emulator state & exit", mon_exit },
|
||||
{ "quit", "Quit emulator WITHOUT saving its state", mon_quit }
|
||||
static const struct TEntry table[] = {
|
||||
{"help", "Print this information", Help },
|
||||
{"run", "Run the emulator with current CPU status", run },
|
||||
{"?", "<addr>, Check address mapping", map_check},
|
||||
{"r", "<addr> [count], Read nibbles from memory", r },
|
||||
{"w", "<addr> [n]..., Write nibbles into memory", w },
|
||||
{"d", "<addr> [count], Disassemble starting from 'addr'", d },
|
||||
{"cpu", "Print CPU status", cpu },
|
||||
{"map", "Print the contents of the module map table", map },
|
||||
{"debug", "Set the debugging level", debug },
|
||||
{"reset", "Reset CPU", reset },
|
||||
{"exit", "Save emulator state & exit", mon_exit },
|
||||
{"quit", "Quit emulator WITHOUT saving its state", mon_quit }
|
||||
};
|
||||
|
||||
/* Invoke the command 'tk' and return a status code */
|
||||
static int InvokeCommand(char *tk)
|
||||
static int InvokeCommand( char* tk )
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<TableSize(table) && strcmp(tk, table[i].name); i++);
|
||||
return i==TableSize(table) ? FAILED : table[i].function();
|
||||
int i;
|
||||
for ( i = 0; i < TableSize( table ) && strcmp( tk, table[ i ].name ); i++ )
|
||||
;
|
||||
return i == TableSize( table ) ? FAILED : table[ i ].function();
|
||||
}
|
||||
|
||||
/* Print help information */
|
||||
static int Help(void)
|
||||
static int Help( void )
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<TableSize(table); i++)
|
||||
printf("%s\t\t%s\n", table[i].name, table[i].desc);
|
||||
int i;
|
||||
for ( i = 0; i < TableSize( table ); i++ )
|
||||
printf( "%s\t\t%s\n", table[ i ].name, table[ i ].desc );
|
||||
|
||||
return OK;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Handler for SIGINT during monitor execution */
|
||||
static void sigint_handler(int s)
|
||||
{
|
||||
EmulatorIntRequest();
|
||||
}
|
||||
|
||||
static void sigint_handler( int s ) { EmulatorIntRequest(); }
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -322,58 +319,53 @@ static void sigint_handler(int s)
|
|||
This function implements a very simple interactive monitor.
|
||||
|
||||
.call :
|
||||
Monitor();
|
||||
Monitor();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
CPU_W_BAD_MONITOR_CMD
|
||||
From lower level modules
|
||||
CPU_W_BAD_MONITOR_CMD
|
||||
From lower level modules
|
||||
.notes :
|
||||
1.1, 18-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void Monitor(void)
|
||||
void Monitor( void )
|
||||
{
|
||||
char cmd[LINE_BUFFER_SIZE];
|
||||
char old_cmd[LINE_BUFFER_SIZE];
|
||||
char *tk;
|
||||
|
||||
/* Clear old_cmd buffer */
|
||||
strcpy(old_cmd, "");
|
||||
char cmd[ LINE_BUFFER_SIZE ];
|
||||
char old_cmd[ LINE_BUFFER_SIZE ];
|
||||
char* tk;
|
||||
|
||||
/* Establish SIGINT handler */
|
||||
signal(SIGINT, sigint_handler);
|
||||
/* Clear old_cmd buffer */
|
||||
strcpy( old_cmd, "" );
|
||||
|
||||
/* Infinite loop; it's exited only when a condition is signalled */
|
||||
while(1)
|
||||
{
|
||||
/* Write prompt */
|
||||
fputs(PROMPT, stdout);
|
||||
fflush(stdout);
|
||||
/* Establish SIGINT handler */
|
||||
signal( SIGINT, sigint_handler );
|
||||
|
||||
if(fgets(cmd, LINE_BUFFER_SIZE, stdin) == (char *)NULL ||
|
||||
(tk = strtok(cmd, TOK_DELIMITERS)) == (char *)NULL)
|
||||
{
|
||||
/* New command empty; try old command */
|
||||
if((tk = strtok(old_cmd, TOK_DELIMITERS)) != (char *)NULL)
|
||||
if(InvokeCommand(tk))
|
||||
ChfCondition CPU_W_BAD_MONITOR_CMD, CHF_WARNING, tk ChfEnd;
|
||||
ChfSignal();
|
||||
/* Infinite loop; it's exited only when a condition is signalled */
|
||||
while ( 1 ) {
|
||||
/* Write prompt */
|
||||
fputs( PROMPT, stdout );
|
||||
fflush( stdout );
|
||||
|
||||
if ( fgets( cmd, LINE_BUFFER_SIZE, stdin ) == ( char* )NULL || ( tk = strtok( cmd, TOK_DELIMITERS ) ) == ( char* )NULL ) {
|
||||
/* New command empty; try old command */
|
||||
if ( ( tk = strtok( old_cmd, TOK_DELIMITERS ) ) != ( char* )NULL )
|
||||
if ( InvokeCommand( tk ) )
|
||||
ChfCondition CPU_W_BAD_MONITOR_CMD, CHF_WARNING, tk ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else {
|
||||
/* Save command */
|
||||
strcpy( old_cmd, cmd );
|
||||
|
||||
/* New command */
|
||||
if ( InvokeCommand( tk ) ) {
|
||||
ChfCondition CPU_W_BAD_MONITOR_CMD, CHF_WARNING, tk ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Save command */
|
||||
strcpy(old_cmd, cmd);
|
||||
|
||||
/* New command */
|
||||
if(InvokeCommand(tk))
|
||||
{
|
||||
ChfCondition CPU_W_BAD_MONITOR_CMD, CHF_WARNING, tk ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
213
src/pack.c
213
src/pack.c
|
@ -83,24 +83,22 @@ static char rcs_id[] = "$Id";
|
|||
#include "cpu.h"
|
||||
#include "disk_io.h"
|
||||
|
||||
#define CHF_MODULE_ID UTIL_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID UTIL_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
/* Maximum size of source ROM (bytes) handled by this utility; set to
|
||||
a reasonable value
|
||||
*/
|
||||
#define MAX_SRC_SIZE (4*1024*1024)
|
||||
|
||||
#define MAX_SRC_SIZE ( 4 * 1024 * 1024 )
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf parameters - Do not change.
|
||||
The ABNORMAL_EXIT_CODE is taken from stdlib.h (EXIT_FAILURE)
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define CONDITION_STACK_SIZE 16
|
||||
#define HANDLER_STACK_SIZE 8
|
||||
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
||||
#define CONDITION_STACK_SIZE 16
|
||||
#define HANDLER_STACK_SIZE 8
|
||||
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
||||
|
||||
/* Conditional prefix and mandatory suffix to make a message catalog
|
||||
name from cat_base_name.
|
||||
|
@ -108,30 +106,26 @@ static char rcs_id[] = "$Id";
|
|||
static const char cat_prefix[] = "./";
|
||||
static const char cat_suffix[] = ".cat";
|
||||
|
||||
#define CAT_PREFIX_LEN (sizeof(cat_prefix)+1)
|
||||
#define CAT_SUFFIX_LEN (sizeof(cat_suffix)+1)
|
||||
#define CAT_PREFIX_LEN ( sizeof( cat_prefix ) + 1 )
|
||||
#define CAT_SUFFIX_LEN ( sizeof( cat_suffix ) + 1 )
|
||||
|
||||
/* Message catalog base_name */
|
||||
static const char cat_base_name[] = "saturn";
|
||||
|
||||
|
||||
/* Condition codes used by this utility */
|
||||
#define UTIL_I_PACK_USAGE 1
|
||||
#define UTIL_F_PACK_CMD_LINE 2
|
||||
#define UTIL_F_PACK_STAT 3
|
||||
#define UTIL_F_PACK_SRC_SIZE 4
|
||||
#define UTIL_F_PACK_MALLOC 5
|
||||
#define UTIL_F_PACK_OPEN 6
|
||||
#define UTIL_F_PACK_READ 7
|
||||
#define UTIL_F_PACK_WRITE_NIBBLES 8
|
||||
|
||||
|
||||
#define UTIL_I_PACK_USAGE 1
|
||||
#define UTIL_F_PACK_CMD_LINE 2
|
||||
#define UTIL_F_PACK_STAT 3
|
||||
#define UTIL_F_PACK_SRC_SIZE 4
|
||||
#define UTIL_F_PACK_MALLOC 5
|
||||
#define UTIL_F_PACK_OPEN 6
|
||||
#define UTIL_F_PACK_READ 7
|
||||
#define UTIL_F_PACK_WRITE_NIBBLES 8
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : main
|
||||
|
@ -144,150 +138,131 @@ static const char cat_base_name[] = "saturn";
|
|||
3.6, 2-Oct-2000, creation
|
||||
|
||||
.- */
|
||||
int main(int argc, char *argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
char *cat_name; /* Message catalog name */
|
||||
struct stat statb; /* stat() buffer on source file */
|
||||
char *b; /* Source buffer */
|
||||
Nibble *nb; /* Nibble buffer */
|
||||
int d; /* Source file descriptor */
|
||||
char* cat_name; /* Message catalog name */
|
||||
struct stat statb; /* stat() buffer on source file */
|
||||
char* b; /* Source buffer */
|
||||
Nibble* nb; /* Nibble buffer */
|
||||
int d; /* Source file descriptor */
|
||||
int i;
|
||||
int st;
|
||||
|
||||
if((cat_name = malloc(sizeof(cat_base_name)
|
||||
+CAT_PREFIX_LEN+CAT_SUFFIX_LEN+1))
|
||||
== NULL)
|
||||
{
|
||||
fprintf(stderr, "Cat_name initialization failed\n");
|
||||
exit(ABNORMAL_EXIT_CODE);
|
||||
if ( ( cat_name = malloc( sizeof( cat_base_name ) + CAT_PREFIX_LEN + CAT_SUFFIX_LEN + 1 ) ) == NULL ) {
|
||||
fprintf( stderr, "Cat_name initialization failed\n" );
|
||||
exit( ABNORMAL_EXIT_CODE );
|
||||
}
|
||||
|
||||
/* Generate catalog name, without optional prefix */
|
||||
strcpy(cat_name, cat_base_name);
|
||||
strcat(cat_name, cat_suffix);
|
||||
strcpy( cat_name, cat_base_name );
|
||||
strcat( cat_name, cat_suffix );
|
||||
|
||||
/* Chf initialization with msgcat subsystem;
|
||||
notice that on some systems (e.g. Digital UNIX) catopen() can succeed
|
||||
even if it was not able to open the right message catalog; better
|
||||
try it now.
|
||||
*/
|
||||
if((st = ChfMsgcatInit(
|
||||
argv[0], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||
)) != CHF_S_OK
|
||||
||
|
||||
ChfGetMessage(CHF_MODULE_ID, UTIL_I_PACK_USAGE, NULL) == NULL)
|
||||
{
|
||||
if(st != CHF_S_OK && st != CHF_F_CATOPEN)
|
||||
{
|
||||
fprintf(stderr, "Chf initialization failed\n");
|
||||
exit(ABNORMAL_EXIT_CODE);
|
||||
}
|
||||
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ||
|
||||
ChfGetMessage( CHF_MODULE_ID, UTIL_I_PACK_USAGE, NULL ) == NULL ) {
|
||||
if ( st != CHF_S_OK && st != CHF_F_CATOPEN ) {
|
||||
fprintf( stderr, "Chf initialization failed\n" );
|
||||
exit( ABNORMAL_EXIT_CODE );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Default message catalog open failed; trying alternate\n");
|
||||
else {
|
||||
fprintf( stderr, "Default message catalog open failed; trying alternate\n" );
|
||||
|
||||
/* Bring down Chf before initializing it again */
|
||||
if(st == CHF_S_OK) ChfExit();
|
||||
/* Bring down Chf before initializing it again */
|
||||
if ( st == CHF_S_OK )
|
||||
ChfExit();
|
||||
|
||||
/* Try alternate message catalog name (with prefix) */
|
||||
strcpy(cat_name, cat_prefix);
|
||||
strcat(cat_name, cat_base_name);
|
||||
strcat(cat_name, cat_suffix);
|
||||
/* Try alternate message catalog name (with prefix) */
|
||||
strcpy( cat_name, cat_prefix );
|
||||
strcat( cat_name, cat_base_name );
|
||||
strcat( cat_name, cat_suffix );
|
||||
|
||||
if((st = ChfMsgcatInit(
|
||||
argv[0], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||
)) != CHF_S_OK
|
||||
||
|
||||
ChfGetMessage(CHF_MODULE_ID, UTIL_I_PACK_USAGE, NULL) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Alternate Chf initialization failed\n");
|
||||
exit(ABNORMAL_EXIT_CODE);
|
||||
}
|
||||
}
|
||||
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ||
|
||||
ChfGetMessage( CHF_MODULE_ID, UTIL_I_PACK_USAGE, NULL ) == NULL ) {
|
||||
fprintf( stderr, "Alternate Chf initialization failed\n" );
|
||||
exit( ABNORMAL_EXIT_CODE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cat_name no longer needed */
|
||||
free(cat_name);
|
||||
free( cat_name );
|
||||
|
||||
/* Now, do some useful work; pack argv[1] into argv[2] */
|
||||
if(argc != 3)
|
||||
{
|
||||
ChfCondition UTIL_I_PACK_USAGE, CHF_INFO ChfEnd;
|
||||
ChfCondition UTIL_F_PACK_CMD_LINE, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
if ( argc != 3 ) {
|
||||
ChfCondition UTIL_I_PACK_USAGE, CHF_INFO ChfEnd;
|
||||
ChfCondition UTIL_F_PACK_CMD_LINE, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Get the size of the source file */
|
||||
if(stat(argv[1], &statb))
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition UTIL_F_PACK_STAT, CHF_FATAL, argv[1] ChfEnd;
|
||||
ChfSignal();
|
||||
if ( stat( argv[ 1 ], &statb ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition UTIL_F_PACK_STAT, CHF_FATAL, argv[ 1 ] ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Check that actual size is reasonable */
|
||||
if(statb.st_size > MAX_SRC_SIZE)
|
||||
{
|
||||
ChfCondition UTIL_F_PACK_SRC_SIZE, CHF_FATAL, statb.st_size ChfEnd;
|
||||
ChfSignal();
|
||||
if ( statb.st_size > MAX_SRC_SIZE ) {
|
||||
ChfCondition UTIL_F_PACK_SRC_SIZE, CHF_FATAL, statb.st_size ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Allocate source buffer */
|
||||
if((b = (char *)malloc(statb.st_size)) == (char *)NULL
|
||||
|| (nb = (Nibble *)malloc(sizeof(Nibble) * statb.st_size))
|
||||
== (Nibble *)NULL)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition UTIL_F_PACK_MALLOC, CHF_FATAL, statb.st_size ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ( b = ( char* )malloc( statb.st_size ) ) == ( char* )NULL ||
|
||||
( nb = ( Nibble* )malloc( sizeof( Nibble ) * statb.st_size ) ) == ( Nibble* )NULL ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition UTIL_F_PACK_MALLOC, CHF_FATAL, statb.st_size ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* open/read/close */
|
||||
if((d = open(argv[1], O_RDONLY)) == -1)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition UTIL_F_PACK_OPEN, CHF_FATAL, argv[1] ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ( d = open( argv[ 1 ], O_RDONLY ) ) == -1 ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition UTIL_F_PACK_OPEN, CHF_FATAL, argv[ 1 ] ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
if(read(d, b, statb.st_size) != statb.st_size)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
if ( read( d, b, statb.st_size ) != statb.st_size ) {
|
||||
ChfErrnoCondition;
|
||||
|
||||
(void)close(d);
|
||||
( void )close( d );
|
||||
|
||||
ChfCondition UTIL_F_PACK_READ, CHF_FATAL, argv[1] ChfEnd;
|
||||
ChfSignal();
|
||||
ChfCondition UTIL_F_PACK_READ, CHF_FATAL, argv[ 1 ] ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
(void)close(d);
|
||||
( void )close( d );
|
||||
|
||||
/* Convert char -> Nibble */
|
||||
for(i=0; i<statb.st_size; i++)
|
||||
nb[i] = (Nibble)b[i];
|
||||
for ( i = 0; i < statb.st_size; i++ )
|
||||
nb[ i ] = ( Nibble )b[ i ];
|
||||
|
||||
/* Source buffer no longer needed */
|
||||
free(b);
|
||||
free( b );
|
||||
|
||||
/* Write */
|
||||
if(WriteNibblesToFile(nb, statb.st_size, argv[2]))
|
||||
{
|
||||
ChfCondition UTIL_F_PACK_WRITE_NIBBLES, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
if ( WriteNibblesToFile( nb, statb.st_size, argv[ 2 ] ) ) {
|
||||
ChfCondition UTIL_F_PACK_WRITE_NIBBLES, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
|
562
src/romram.c
562
src/romram.c
|
@ -86,7 +86,7 @@ static char rcs_id[] = "$Id: romram.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* access() */
|
||||
#include <unistd.h> /* access() */
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
|
@ -98,26 +98,24 @@ static char rcs_id[] = "$Id: romram.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
|
||||
#include "args.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
/* 3.2: The rom/ram storage areas are now dynamically allocated in
|
||||
a private struct ModStatus_48. The dynamic allocation is performed during
|
||||
Rom initialization, and the following macro allows us to reuse the
|
||||
existing code with minimal updates.
|
||||
*/
|
||||
static struct ModStatus_48 *mod_status_48;
|
||||
|
||||
#define mod_status_hdw mod_status.hdw
|
||||
#define mod_status_rom mod_status_48->rom
|
||||
#define mod_status_ram mod_status_48->ram
|
||||
#define mod_status_port_1 mod_status_48->port_1
|
||||
#define mod_status_port_2 mod_status_48->port_2
|
||||
static struct ModStatus_48* mod_status_48;
|
||||
|
||||
#define mod_status_hdw mod_status.hdw
|
||||
#define mod_status_rom mod_status_48->rom
|
||||
#define mod_status_ram mod_status_48->ram
|
||||
#define mod_status_port_1 mod_status_48->port_1
|
||||
#define mod_status_port_2 mod_status_48->port_2
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Rom module
|
||||
Rom module
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -130,41 +128,35 @@ static struct ModStatus_48 *mod_status_48;
|
|||
module status structure, and initializes the Rom module.
|
||||
|
||||
.call :
|
||||
RomInit();
|
||||
RomInit();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_F_ROM_INIT
|
||||
MOD_F_MOD_STATUS_ALLOC
|
||||
MOD_I_CALLED
|
||||
MOD_F_ROM_INIT
|
||||
MOD_F_MOD_STATUS_ALLOC
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
void RomInit(void)
|
||||
void RomInit( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RomInit");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomInit" );
|
||||
|
||||
if((mod_status_48 =
|
||||
(struct ModStatus_48 *)malloc(sizeof(struct ModStatus_48)))
|
||||
== (struct ModStatus_48 *)NULL)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_F_MOD_STATUS_ALLOC, CHF_FATAL,
|
||||
sizeof(struct ModStatus_48) ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ( mod_status_48 = ( struct ModStatus_48* )malloc( sizeof( struct ModStatus_48 ) ) ) == ( struct ModStatus_48* )NULL ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_F_MOD_STATUS_ALLOC, CHF_FATAL, sizeof( struct ModStatus_48 ) ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
if(ReadNibblesFromFile(args.rom_file_name, N_ROM_SIZE, mod_status_rom))
|
||||
{
|
||||
ChfCondition MOD_F_ROM_INIT, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ReadNibblesFromFile( args.rom_file_name, N_ROM_SIZE, mod_status_rom ) ) {
|
||||
ChfCondition MOD_F_ROM_INIT, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RomSave
|
||||
|
@ -175,22 +167,18 @@ void RomInit(void)
|
|||
nothing.
|
||||
|
||||
.call :
|
||||
RomSave();
|
||||
RomSave();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void RomSave(void)
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RomSave");
|
||||
}
|
||||
|
||||
void RomSave( void ) { debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomSave" ); }
|
||||
|
||||
/* .+
|
||||
|
||||
|
@ -202,25 +190,24 @@ void RomSave(void)
|
|||
and returns it.
|
||||
|
||||
.call :
|
||||
d = RomRead(rel_address);
|
||||
d = RomRead(rel_address);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Address rel_address, memory address
|
||||
.output :
|
||||
Nibble *d, datum read from memory
|
||||
Nibble *d, datum read from memory
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
1.1, 26-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
Nibble RomRead(Address rel_address)
|
||||
Nibble RomRead( Address rel_address )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RomRead");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomRead" );
|
||||
|
||||
return mod_status_rom[rel_address];
|
||||
return mod_status_rom[ rel_address ];
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RomWrite
|
||||
|
@ -231,30 +218,29 @@ Nibble RomRead(Address rel_address)
|
|||
ROM location. It signals an error condition and does nothing.
|
||||
|
||||
.call :
|
||||
RomWrite(rel_address, datum);
|
||||
RomWrite(rel_address, datum);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_ROM_WRITE
|
||||
MOD_I_CALLED
|
||||
MOD_E_ROM_WRITE
|
||||
.notes :
|
||||
1.1, 26-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
void RomWrite(Address rel_address, Nibble datum)
|
||||
void RomWrite( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RomWrite");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomWrite" );
|
||||
|
||||
ChfCondition MOD_E_ROM_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||
ChfSignal();
|
||||
ChfCondition MOD_E_ROM_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Main Ram module
|
||||
Main Ram module
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -266,32 +252,30 @@ void RomWrite(Address rel_address, Nibble datum)
|
|||
This function initializes the Ram module.
|
||||
|
||||
.call :
|
||||
RamInit();
|
||||
RamInit();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_W_RAM_INIT
|
||||
MOD_I_CALLED
|
||||
MOD_W_RAM_INIT
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
void RamInit(void)
|
||||
void RamInit( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RamInit");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamInit" );
|
||||
|
||||
if(ReadNibblesFromFile(args.ram_file_name, N_RAM_SIZE, mod_status_ram))
|
||||
{
|
||||
ChfCondition MOD_W_RAM_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ReadNibblesFromFile( args.ram_file_name, N_RAM_SIZE, mod_status_ram ) ) {
|
||||
ChfCondition MOD_W_RAM_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
(void)memset(mod_status_ram, 0, sizeof(mod_status_ram));
|
||||
}
|
||||
( void )memset( mod_status_ram, 0, sizeof( mod_status_ram ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RamSave
|
||||
|
@ -301,33 +285,31 @@ void RamInit(void)
|
|||
This function saves the status of the Ram module to disk.
|
||||
|
||||
.call :
|
||||
RamSave();
|
||||
RamSave();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_RAM_SAVE
|
||||
MOD_I_CALLED
|
||||
MOD_E_RAM_SAVE
|
||||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
2.4, 12-Sep-2000, update
|
||||
- upon failure, added push of ChfErrnoCondition to condition stack.
|
||||
|
||||
.- */
|
||||
void RamSave(void)
|
||||
void RamSave( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RamSave");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamSave" );
|
||||
|
||||
if(WriteNibblesToFile(mod_status_ram, N_RAM_SIZE, args.ram_file_name))
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_RAM_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
if ( WriteNibblesToFile( mod_status_ram, N_RAM_SIZE, args.ram_file_name ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_RAM_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RamRead
|
||||
|
@ -338,25 +320,24 @@ void RamSave(void)
|
|||
and returns it.
|
||||
|
||||
.call :
|
||||
d = RamRead(rel_address);
|
||||
d = RamRead(rel_address);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Address rel_address, memory address
|
||||
.output :
|
||||
Nibble *d, datum read from memory
|
||||
Nibble *d, datum read from memory
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
1.1, 26-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
Nibble RamRead(Address rel_address)
|
||||
Nibble RamRead( Address rel_address )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RamRead");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamRead" );
|
||||
|
||||
return mod_status_ram[rel_address];
|
||||
return mod_status_ram[ rel_address ];
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RamWrite
|
||||
|
@ -367,28 +348,27 @@ Nibble RamRead(Address rel_address)
|
|||
of the internal RAM.
|
||||
|
||||
.call :
|
||||
RamWrite(rel_address, datum);
|
||||
RamWrite(rel_address, datum);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
1.1, 26-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
void RamWrite(Address rel_address, Nibble datum)
|
||||
void RamWrite( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RamWrite");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamWrite" );
|
||||
|
||||
mod_status_ram[rel_address] = datum;
|
||||
mod_status_ram[ rel_address ] = datum;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Ce1 module
|
||||
Ce1 module
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -401,33 +381,31 @@ void RamWrite(Address rel_address, Nibble datum)
|
|||
Back Switcher.
|
||||
|
||||
.call :
|
||||
Ce1Init();
|
||||
Ce1Init();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
void Ce1Init(void)
|
||||
void Ce1Init( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Init");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Init" );
|
||||
|
||||
/* Check if bank-switcher accelerators are valid; if not, initialize
|
||||
them to a reasonable value (that is, select Port_2 bank 0).
|
||||
*/
|
||||
if(!mod_status_hdw.accel_valid)
|
||||
{
|
||||
mod_status_hdw.accel_valid = 1;
|
||||
mod_status_hdw.accel.a48.bs_address = (XAddress)0;
|
||||
}
|
||||
/* Check if bank-switcher accelerators are valid; if not, initialize
|
||||
them to a reasonable value (that is, select Port_2 bank 0).
|
||||
*/
|
||||
if ( !mod_status_hdw.accel_valid ) {
|
||||
mod_status_hdw.accel_valid = 1;
|
||||
mod_status_hdw.accel.a48.bs_address = ( XAddress )0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce1Save
|
||||
|
@ -437,28 +415,27 @@ void Ce1Init(void)
|
|||
This function saves the status of the Ce1 module.
|
||||
|
||||
.call :
|
||||
Ce1Save();
|
||||
Ce1Save();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
void Ce1Save(void)
|
||||
void Ce1Save( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Save");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Save" );
|
||||
|
||||
/* Nothing to be done herel the bank-switcher accelerators are saved
|
||||
by the hdw modules
|
||||
*/
|
||||
/* Nothing to be done herel the bank-switcher accelerators are saved
|
||||
by the hdw modules
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce1Read
|
||||
|
@ -471,37 +448,35 @@ void Ce1Save(void)
|
|||
most significant bits of Port_2 addresses when accessing that port.
|
||||
|
||||
.call :
|
||||
d = Ce1Read(rel_address);
|
||||
d = Ce1Read(rel_address);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Address rel_address, memory address
|
||||
.output :
|
||||
Nibble *d, datum read from memory
|
||||
Nibble *d, datum read from memory
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_BS_ADDRESS
|
||||
MOD_I_CALLED
|
||||
MOD_I_BS_ADDRESS
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
Nibble Ce1Read(Address rel_address)
|
||||
Nibble Ce1Read( Address rel_address )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Read");
|
||||
debug1(DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address);
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Read" );
|
||||
debug1( DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||
|
||||
/* Save the read address into the hdw accelerators.
|
||||
bs_address can be directly or-ed with a relative port address to
|
||||
obtain a valid index in Port_2
|
||||
*/
|
||||
/* Save the read address into the hdw accelerators.
|
||||
bs_address can be directly or-ed with a relative port address to
|
||||
obtain a valid index in Port_2
|
||||
*/
|
||||
#ifdef N_PORT_2_BANK
|
||||
mod_status_hdw.accel.a48.bs_address =
|
||||
((XAddress)((rel_address >> 1) & 0x1F) << 18) & (N_PORT_2_SIZE-1);
|
||||
mod_status_hdw.accel.a48.bs_address = ( ( XAddress )( ( rel_address >> 1 ) & 0x1F ) << 18 ) & ( N_PORT_2_SIZE - 1 );
|
||||
#endif
|
||||
|
||||
return (Nibble)0x0;
|
||||
return ( Nibble )0x0;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce1Write
|
||||
|
@ -513,31 +488,30 @@ Nibble Ce1Read(Address rel_address)
|
|||
state of mod_status_hdw.accel.a48.bs_address is *not* changed.
|
||||
|
||||
.call :
|
||||
Ce1Write(rel_address, datum);
|
||||
Ce1Write(rel_address, datum);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_CE1_WRITE
|
||||
MOD_I_CALLED
|
||||
MOD_E_CE1_WRITE
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
void Ce1Write(Address rel_address, Nibble datum)
|
||||
void Ce1Write( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Write");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Write" );
|
||||
|
||||
ChfCondition MOD_E_CE1_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||
ChfSignal();
|
||||
ChfCondition MOD_E_CE1_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Ce2 module
|
||||
Ce2 module
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -549,68 +523,61 @@ void Ce1Write(Address rel_address, Nibble datum)
|
|||
This function initializes the Ce2 module, corresponding to Port 1.
|
||||
|
||||
.call :
|
||||
Ce2Init();
|
||||
Ce2Init();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_W_PORT_1_INIT
|
||||
MOD_I_PORT_1_WP
|
||||
MOD_I_CALLED
|
||||
MOD_W_PORT_1_INIT
|
||||
MOD_I_PORT_1_WP
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
void Ce2Init(void)
|
||||
void Ce2Init( void )
|
||||
{
|
||||
Nibble new_status;
|
||||
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Init");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Init" );
|
||||
|
||||
if(ReadNibblesFromFile(args.port_1_file_name, N_PORT_1_SIZE,
|
||||
mod_status_port_1))
|
||||
{
|
||||
ChfCondition MOD_W_PORT_1_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ReadNibblesFromFile( args.port_1_file_name, N_PORT_1_SIZE, mod_status_port_1 ) ) {
|
||||
ChfCondition MOD_W_PORT_1_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
(void)memset(mod_status_port_1, 0, sizeof(mod_status_port_1));
|
||||
( void )memset( mod_status_port_1, 0, sizeof( mod_status_port_1 ) );
|
||||
|
||||
new_status =
|
||||
mod_status_hdw.card_status & ~(CE2_CARD_PRESENT|CE2_CARD_WE);
|
||||
new_status = mod_status_hdw.card_status & ~( CE2_CARD_PRESENT | CE2_CARD_WE );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Card present; check write protection */
|
||||
new_status = mod_status_hdw.card_status | CE2_CARD_PRESENT;
|
||||
else {
|
||||
/* Card present; check write protection */
|
||||
new_status = mod_status_hdw.card_status | CE2_CARD_PRESENT;
|
||||
|
||||
if(access(args.port_1_file_name, W_OK) == 0)
|
||||
new_status |= CE2_CARD_WE;
|
||||
if ( access( args.port_1_file_name, W_OK ) == 0 )
|
||||
new_status |= CE2_CARD_WE;
|
||||
|
||||
else
|
||||
{
|
||||
new_status &= ~CE2_CARD_WE;
|
||||
else {
|
||||
new_status &= ~CE2_CARD_WE;
|
||||
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_I_PORT_1_WP, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_I_PORT_1_WP, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
if(new_status != mod_status_hdw.card_status)
|
||||
{
|
||||
/* card_status changed; update, set MP bit in HST and post
|
||||
interrupt request.
|
||||
*/
|
||||
mod_status_hdw.card_status = new_status;
|
||||
cpu_status.HST |= HST_MP_MASK;
|
||||
CpuIntRequest(INT_REQUEST_IRQ);
|
||||
if ( new_status != mod_status_hdw.card_status ) {
|
||||
/* card_status changed; update, set MP bit in HST and post
|
||||
interrupt request.
|
||||
*/
|
||||
mod_status_hdw.card_status = new_status;
|
||||
cpu_status.HST |= HST_MP_MASK;
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce2Save
|
||||
|
@ -621,35 +588,31 @@ void Ce2Init(void)
|
|||
not write-protected.
|
||||
|
||||
.call :
|
||||
Ce2Save();
|
||||
Ce2Save();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_PORT_1_SAVE
|
||||
MOD_I_CALLED
|
||||
MOD_E_PORT_1_SAVE
|
||||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
void Ce2Save(void)
|
||||
void Ce2Save( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Save");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Save" );
|
||||
|
||||
/* Attempt to save only if port is write-enabled */
|
||||
if((mod_status_hdw.card_status & CE2_CARD_WE) &&
|
||||
WriteNibblesToFile(mod_status_port_1, N_PORT_1_SIZE,
|
||||
args.port_1_file_name))
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_PORT_1_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ( mod_status_hdw.card_status & CE2_CARD_WE ) && WriteNibblesToFile( mod_status_port_1, N_PORT_1_SIZE, args.port_1_file_name ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_PORT_1_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce2Read
|
||||
|
@ -659,26 +622,25 @@ void Ce2Save(void)
|
|||
This function reads a nibble from the Ce2 module.
|
||||
|
||||
.call :
|
||||
d = Ce2Read(rel_address)
|
||||
d = Ce2Read(rel_address)
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Address rel_address, memory address
|
||||
.output :
|
||||
Nibble *d, datum read from memory
|
||||
Nibble *d, datum read from memory
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
Nibble Ce2Read(Address rel_address)
|
||||
Nibble Ce2Read( Address rel_address )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Read");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Read" );
|
||||
|
||||
return mod_status_port_1[rel_address];
|
||||
return mod_status_port_1[ rel_address ];
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce2Write
|
||||
|
@ -688,29 +650,28 @@ Nibble Ce2Read(Address rel_address)
|
|||
This function writes a nibble to the Ce2 module.
|
||||
|
||||
.call :
|
||||
Ce2Write(rel_address, datum);
|
||||
Ce2Write(rel_address, datum);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
void Ce2Write(Address rel_address, Nibble datum)
|
||||
void Ce2Write( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Write");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Write" );
|
||||
|
||||
mod_status_port_1[rel_address] = datum;
|
||||
mod_status_port_1[ rel_address ] = datum;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
NCe3 module
|
||||
NCe3 module
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -723,76 +684,68 @@ void Ce2Write(Address rel_address, Nibble datum)
|
|||
(bank switched) port 2.
|
||||
|
||||
.call :
|
||||
NCe3Init();
|
||||
NCe3Init();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_W_PORT_2_INIT
|
||||
MOD_I_PORT_2_WP
|
||||
MOD_I_CALLED
|
||||
MOD_W_PORT_2_INIT
|
||||
MOD_I_PORT_2_WP
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
void NCe3Init(void)
|
||||
void NCe3Init( void )
|
||||
{
|
||||
Nibble new_status;
|
||||
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Init");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Init" );
|
||||
|
||||
#ifdef N_PORT_2_BANK
|
||||
if(ReadNibblesFromFile(args.port_2_file_name, N_PORT_2_SIZE,
|
||||
mod_status_port_2))
|
||||
{
|
||||
ChfCondition MOD_W_PORT_2_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ReadNibblesFromFile( args.port_2_file_name, N_PORT_2_SIZE, mod_status_port_2 ) ) {
|
||||
ChfCondition MOD_W_PORT_2_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
(void)memset(mod_status_port_2, 0, sizeof(mod_status_port_2));
|
||||
( void )memset( mod_status_port_2, 0, sizeof( mod_status_port_2 ) );
|
||||
|
||||
new_status =
|
||||
mod_status_hdw.card_status & ~(NCE3_CARD_PRESENT|NCE3_CARD_WE);
|
||||
new_status = mod_status_hdw.card_status & ~( NCE3_CARD_PRESENT | NCE3_CARD_WE );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Card present; check write protection */
|
||||
new_status = mod_status_hdw.card_status | NCE3_CARD_PRESENT;
|
||||
else {
|
||||
/* Card present; check write protection */
|
||||
new_status = mod_status_hdw.card_status | NCE3_CARD_PRESENT;
|
||||
|
||||
if(access(args.port_2_file_name, W_OK) == 0)
|
||||
new_status |= NCE3_CARD_WE;
|
||||
if ( access( args.port_2_file_name, W_OK ) == 0 )
|
||||
new_status |= NCE3_CARD_WE;
|
||||
|
||||
else
|
||||
{
|
||||
new_status &= ~NCE3_CARD_WE;
|
||||
else {
|
||||
new_status &= ~NCE3_CARD_WE;
|
||||
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_I_PORT_2_WP, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_I_PORT_2_WP, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* If N_PORT_2_BANK is undefined, Port 2 is not emulated */
|
||||
new_status =
|
||||
mod_status_hdw.card_status & ~(NCE3_CARD_PRESENT|NCE3_CARD_WE);
|
||||
new_status = mod_status_hdw.card_status & ~( NCE3_CARD_PRESENT | NCE3_CARD_WE );
|
||||
|
||||
#endif
|
||||
|
||||
if(new_status != mod_status_hdw.card_status)
|
||||
{
|
||||
/* card_status changed; update, set MP bit in HST and post
|
||||
interrupt request.
|
||||
*/
|
||||
mod_status_hdw.card_status = new_status;
|
||||
cpu_status.HST |= HST_MP_MASK;
|
||||
CpuIntRequest(INT_REQUEST_IRQ);
|
||||
if ( new_status != mod_status_hdw.card_status ) {
|
||||
/* card_status changed; update, set MP bit in HST and post
|
||||
interrupt request.
|
||||
*/
|
||||
mod_status_hdw.card_status = new_status;
|
||||
cpu_status.HST |= HST_MP_MASK;
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : NCe3Save
|
||||
|
@ -802,37 +755,33 @@ void NCe3Init(void)
|
|||
This function saves the status of the NCe3 module.
|
||||
|
||||
.call :
|
||||
NCe3Save();
|
||||
NCe3Save();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_PORT_2_SAVE
|
||||
MOD_I_CALLED
|
||||
MOD_E_PORT_2_SAVE
|
||||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
|
||||
.- */
|
||||
void NCe3Save(void)
|
||||
void NCe3Save( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Save");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Save" );
|
||||
|
||||
#ifdef N_PORT_2_BANK
|
||||
/* Attempt to save only if port is write-enabled */
|
||||
if((mod_status_hdw.card_status & NCE3_CARD_WE) &&
|
||||
WriteNibblesToFile(mod_status_port_2, N_PORT_2_SIZE,
|
||||
args.port_2_file_name))
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_PORT_2_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ( mod_status_hdw.card_status & NCE3_CARD_WE ) && WriteNibblesToFile( mod_status_port_2, N_PORT_2_SIZE, args.port_2_file_name ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_PORT_2_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : NCe3Read
|
||||
|
@ -842,37 +791,35 @@ void NCe3Save(void)
|
|||
This function reads a nibble from the NCe3 module.
|
||||
|
||||
.call :
|
||||
d = NCe3Read(rel_address)
|
||||
d = NCe3Read(rel_address)
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Address rel_address, memory address
|
||||
.output :
|
||||
Nibble *d, datum read from memory
|
||||
Nibble *d, datum read from memory
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_NCE3_READ
|
||||
MOD_I_CALLED
|
||||
MOD_E_NCE3_READ
|
||||
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
Nibble NCe3Read(Address rel_address)
|
||||
Nibble NCe3Read( Address rel_address )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Read");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Read" );
|
||||
|
||||
#ifdef N_PORT_2_BANK
|
||||
return
|
||||
mod_status_port_2[rel_address | mod_status_hdw.accel.a48.bs_address];
|
||||
return mod_status_port_2[ rel_address | mod_status_hdw.accel.a48.bs_address ];
|
||||
|
||||
#else
|
||||
ChfCondition MOD_E_NCE3_READ, CHF_ERROR, rel_address ChfEnd;
|
||||
ChfSignal();
|
||||
return (Nibble)0;
|
||||
return ( Nibble )0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : NCe3Write
|
||||
|
@ -883,28 +830,27 @@ Nibble NCe3Read(Address rel_address)
|
|||
it is not currently implemented.
|
||||
|
||||
.call :
|
||||
NCe3Write(rel_address, datum);
|
||||
NCe3Write(rel_address, datum);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_NCE3_WRITE
|
||||
MOD_I_CALLED
|
||||
MOD_E_NCE3_WRITE
|
||||
|
||||
.notes :
|
||||
1.1, 23-Jan-1998, creation
|
||||
2.4, 11-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
void NCe3Write(Address rel_address, Nibble datum)
|
||||
void NCe3Write( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Write");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Write" );
|
||||
|
||||
#ifdef N_PORT_2_BANK
|
||||
mod_status_port_2[rel_address | mod_status_hdw.accel.a48.bs_address]
|
||||
= datum;
|
||||
mod_status_port_2[ rel_address | mod_status_hdw.accel.a48.bs_address ] = datum;
|
||||
|
||||
#else
|
||||
ChfCondition MOD_E_NCE3_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||
|
|
456
src/romram49.c
456
src/romram49.c
|
@ -98,7 +98,7 @@ static char rcs_id[] = "$Id: romram49.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
|||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* access() */
|
||||
#include <unistd.h> /* access() */
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
|
@ -111,28 +111,26 @@ static char rcs_id[] = "$Id: romram49.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
|||
|
||||
#include "args.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
#define FLASH_VIEW_SELECTOR 0x40000
|
||||
#define FLASH_BANK_MASK 0x3FFFF
|
||||
|
||||
#define FLASH_VIEW_SELECTOR 0x40000
|
||||
#define FLASH_BANK_MASK 0x3FFFF
|
||||
#define CE2_RAM_OFFSET 0x80000
|
||||
#define NCE3_RAM_OFFSET 0xC0000
|
||||
#define NCE3_RAM_MASK 0x3FFFF
|
||||
|
||||
#define CE2_RAM_OFFSET 0x80000
|
||||
#define NCE3_RAM_OFFSET 0xC0000
|
||||
#define NCE3_RAM_MASK 0x3FFFF
|
||||
|
||||
#define HDW_LCR_OFFSET 0x1C
|
||||
#define LCR_LED 0x8
|
||||
#define HDW_LCR_OFFSET 0x1C
|
||||
#define LCR_LED 0x8
|
||||
|
||||
/* 3.3: This is no longer static, because flash49.c needs access to
|
||||
the Flash ROM array... yes, I know this is not particularly nice,
|
||||
*/
|
||||
struct ModStatus_49 *mod_status_49;
|
||||
|
||||
struct ModStatus_49* mod_status_49;
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Rom module
|
||||
Rom module
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -145,42 +143,35 @@ struct ModStatus_49 *mod_status_49;
|
|||
module status structure, and initializes the Flash Rom module.
|
||||
|
||||
.call :
|
||||
RomInit49();
|
||||
RomInit49();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_F_ROM_INIT
|
||||
MOD_F_MOD_STATUS_ALLOC
|
||||
MOD_I_CALLED
|
||||
MOD_F_ROM_INIT
|
||||
MOD_F_MOD_STATUS_ALLOC
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void RomInit49(void)
|
||||
void RomInit49( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RomInit49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomInit49" );
|
||||
|
||||
if((mod_status_49 =
|
||||
(struct ModStatus_49 *)malloc(sizeof(struct ModStatus_49)))
|
||||
== (struct ModStatus_49 *)NULL)
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_F_MOD_STATUS_ALLOC, CHF_FATAL,
|
||||
sizeof(struct ModStatus_49) ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ( mod_status_49 = ( struct ModStatus_49* )malloc( sizeof( struct ModStatus_49 ) ) ) == ( struct ModStatus_49* )NULL ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_F_MOD_STATUS_ALLOC, CHF_FATAL, sizeof( struct ModStatus_49 ) ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
if(ReadNibblesFromFile(args.rom_file_name, N_FLASH_SIZE_49,
|
||||
mod_status_49->flash))
|
||||
{
|
||||
ChfCondition MOD_F_ROM_INIT, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ReadNibblesFromFile( args.rom_file_name, N_FLASH_SIZE_49, mod_status_49->flash ) ) {
|
||||
ChfCondition MOD_F_ROM_INIT, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RomSave49
|
||||
|
@ -190,33 +181,30 @@ void RomInit49(void)
|
|||
This function saves the status of the Flash Rom.
|
||||
|
||||
.call :
|
||||
RomSave49();
|
||||
RomSave49();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_ROM_SAVE
|
||||
MOD_I_CALLED
|
||||
MOD_E_ROM_SAVE
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
3.3, 25-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
void RomSave49(void)
|
||||
void RomSave49( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RomSave49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomSave49" );
|
||||
|
||||
if(WriteNibblesToFile(mod_status_49->flash, N_FLASH_SIZE_49,
|
||||
args.rom_file_name))
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_ROM_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
if ( WriteNibblesToFile( mod_status_49->flash, N_FLASH_SIZE_49, args.rom_file_name ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_ROM_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RomRead49
|
||||
|
@ -227,30 +215,28 @@ void RomSave49(void)
|
|||
'rel_address' and returns it.
|
||||
|
||||
.call :
|
||||
d = RomRead49(rel_address);
|
||||
d = RomRead49(rel_address);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Address rel_address, memory address
|
||||
.output :
|
||||
Nibble *d, datum read from memory
|
||||
Nibble *d, datum read from memory
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
Nibble RomRead49(Address rel_address)
|
||||
Nibble RomRead49( Address rel_address )
|
||||
{
|
||||
register XAddress view;
|
||||
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RomRead49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomRead49" );
|
||||
|
||||
view = mod_status.hdw.accel.a49.view[
|
||||
(rel_address & FLASH_VIEW_SELECTOR) != 0];
|
||||
|
||||
return mod_status_49->flash[view | (rel_address & FLASH_BANK_MASK)];
|
||||
view = mod_status.hdw.accel.a49.view[ ( rel_address & FLASH_VIEW_SELECTOR ) != 0 ];
|
||||
|
||||
return mod_status_49->flash[ view | ( rel_address & FLASH_BANK_MASK ) ];
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RomWrite49
|
||||
|
@ -266,31 +252,30 @@ Nibble RomRead49(Address rel_address)
|
|||
Those cycles are silently ignored.
|
||||
|
||||
.call :
|
||||
RomWrite49(rel_address, datum);
|
||||
RomWrite49(rel_address, datum);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
3.3, 26-Sep-2000, implemented
|
||||
|
||||
.- */
|
||||
void RomWrite49(Address rel_address, Nibble datum)
|
||||
void RomWrite49( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RomWrite49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomWrite49" );
|
||||
|
||||
/* Ignore write cycles through ROM controller; HP49 ROM 1.19-4
|
||||
can do this when to ON key is pressed.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Main Ram module
|
||||
Main Ram module
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -302,33 +287,30 @@ void RomWrite49(Address rel_address, Nibble datum)
|
|||
This function initializes the Ram module.
|
||||
|
||||
.call :
|
||||
RamInit49();
|
||||
RamInit49();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_W_RAM_INIT
|
||||
MOD_I_CALLED
|
||||
MOD_W_RAM_INIT
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void RamInit49(void)
|
||||
void RamInit49( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RamInit49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamInit49" );
|
||||
|
||||
if(ReadNibblesFromFile(args.ram_file_name, N_RAM_SIZE_49,
|
||||
mod_status_49->ram))
|
||||
{
|
||||
ChfCondition MOD_W_RAM_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
if ( ReadNibblesFromFile( args.ram_file_name, N_RAM_SIZE_49, mod_status_49->ram ) ) {
|
||||
ChfCondition MOD_W_RAM_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
(void)memset(mod_status_49->ram, 0, sizeof(mod_status_49->ram));
|
||||
( void )memset( mod_status_49->ram, 0, sizeof( mod_status_49->ram ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RamSave49
|
||||
|
@ -338,32 +320,29 @@ void RamInit49(void)
|
|||
This function saves the status of the Ram module to disk.
|
||||
|
||||
.call :
|
||||
RamSave49();
|
||||
RamSave49();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_E_RAM_SAVE
|
||||
MOD_I_CALLED
|
||||
MOD_E_RAM_SAVE
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void RamSave49(void)
|
||||
void RamSave49( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RamSave49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamSave49" );
|
||||
|
||||
if(WriteNibblesToFile(mod_status_49->ram, N_RAM_SIZE_49,
|
||||
args.ram_file_name))
|
||||
{
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_RAM_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
if ( WriteNibblesToFile( mod_status_49->ram, N_RAM_SIZE_49, args.ram_file_name ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_RAM_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RamRead49
|
||||
|
@ -374,25 +353,24 @@ void RamSave49(void)
|
|||
and returns it.
|
||||
|
||||
.call :
|
||||
d = RamRead49(rel_address);
|
||||
d = RamRead49(rel_address);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Address rel_address, memory address
|
||||
.output :
|
||||
Nibble *d, datum read from memory
|
||||
Nibble *d, datum read from memory
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
Nibble RamRead49(Address rel_address)
|
||||
Nibble RamRead49( Address rel_address )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RamRead49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamRead49" );
|
||||
|
||||
return mod_status_49->ram[rel_address];
|
||||
return mod_status_49->ram[ rel_address ];
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RamWrite49
|
||||
|
@ -403,28 +381,27 @@ Nibble RamRead49(Address rel_address)
|
|||
of the internal RAM.
|
||||
|
||||
.call :
|
||||
RamWrite49(rel_address, datum);
|
||||
RamWrite49(rel_address, datum);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void RamWrite49(Address rel_address, Nibble datum)
|
||||
void RamWrite49( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RamWrite49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamWrite49" );
|
||||
|
||||
mod_status_49->ram[rel_address] = datum;
|
||||
mod_status_49->ram[ rel_address ] = datum;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Ce1 module
|
||||
Ce1 module
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -437,34 +414,31 @@ void RamWrite49(Address rel_address, Nibble datum)
|
|||
Back Switcher.
|
||||
|
||||
.call :
|
||||
Ce1Init49();
|
||||
Ce1Init49();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void Ce1Init49(void)
|
||||
void Ce1Init49( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Init49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Init49" );
|
||||
|
||||
/* Check if bank-switcher accelerators are valid; if not, initialize
|
||||
them to a reasonable value (that is, select Flash Rom bank 0 for
|
||||
both views).
|
||||
*/
|
||||
if(!mod_status.hdw.accel_valid)
|
||||
{
|
||||
mod_status.hdw.accel_valid = 1;
|
||||
mod_status.hdw.accel.a49.view[0] =
|
||||
mod_status.hdw.accel.a49.view[1] = (XAddress)0;
|
||||
if ( !mod_status.hdw.accel_valid ) {
|
||||
mod_status.hdw.accel_valid = 1;
|
||||
mod_status.hdw.accel.a49.view[ 0 ] = mod_status.hdw.accel.a49.view[ 1 ] = ( XAddress )0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce1Save49
|
||||
|
@ -474,40 +448,36 @@ void Ce1Init49(void)
|
|||
This function saves the status of the Ce1 module.
|
||||
|
||||
.call :
|
||||
Ce1Save49();
|
||||
Ce1Save49();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void Ce1Save49(void)
|
||||
void Ce1Save49( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Save49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Save49" );
|
||||
|
||||
/* Nothing to be done here; the bank-switcher accelerators are saved
|
||||
by the hdw modules
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/* This fragment of code is used by both Ce1Read49() and Ce1Write49();
|
||||
the macro definition is here to allow us to write the code once and
|
||||
use it many times without incurring a function call overhead.
|
||||
*/
|
||||
#define Ce1SetViews \
|
||||
{ \
|
||||
mod_status.hdw.accel.a49.view[0] = \
|
||||
((XAddress)((rel_address >> 5) & 0x03) << 18); \
|
||||
\
|
||||
mod_status.hdw.accel.a49.view[1] = \
|
||||
((XAddress)((rel_address >> 1) & 0x0F) << 18); \
|
||||
}
|
||||
|
||||
#define Ce1SetViews \
|
||||
{ \
|
||||
mod_status.hdw.accel.a49.view[ 0 ] = ( ( XAddress )( ( rel_address >> 5 ) & 0x03 ) << 18 ); \
|
||||
\
|
||||
mod_status.hdw.accel.a49.view[ 1 ] = ( ( XAddress )( ( rel_address >> 1 ) & 0x0F ) << 18 ); \
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
||||
|
@ -522,33 +492,32 @@ void Ce1Save49(void)
|
|||
most significant bits of addresses when accessing Flash Rom.
|
||||
|
||||
.call :
|
||||
d = Ce1Read49(rel_address);
|
||||
d = Ce1Read49(rel_address);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Address rel_address, memory address
|
||||
.output :
|
||||
Nibble *d, datum read from memory
|
||||
Nibble *d, datum read from memory
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_BS_ADDRESS
|
||||
MOD_I_CALLED
|
||||
MOD_I_BS_ADDRESS
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
Nibble Ce1Read49(Address rel_address)
|
||||
Nibble Ce1Read49( Address rel_address )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Read49");
|
||||
debug1(DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address);
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Read49" );
|
||||
debug1( DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||
|
||||
/* Save the ROM view base addresses address into the hdw accelerators.
|
||||
view[] can be directly or-ed with a relative port address to
|
||||
obtain a valid index in Flash Rom.
|
||||
*/
|
||||
Ce1SetViews;
|
||||
/* Save the ROM view base addresses address into the hdw accelerators.
|
||||
view[] can be directly or-ed with a relative port address to
|
||||
obtain a valid index in Flash Rom.
|
||||
*/
|
||||
Ce1SetViews;
|
||||
|
||||
return (Nibble)0x0;
|
||||
return ( Nibble )0x0;
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce1Write49
|
||||
|
@ -562,34 +531,33 @@ Nibble Ce1Read49(Address rel_address)
|
|||
most significant bits of addresses when accessing Flash Rom.
|
||||
|
||||
.call :
|
||||
Ce1Write49(rel_address, datum);
|
||||
Ce1Write49(rel_address, datum);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory; ignored
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory; ignored
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_BS_ADDRESS
|
||||
MOD_I_CALLED
|
||||
MOD_I_BS_ADDRESS
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void Ce1Write49(Address rel_address, Nibble datum)
|
||||
void Ce1Write49( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Write49");
|
||||
debug1(DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address);
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Write49" );
|
||||
debug1( DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||
|
||||
/* Save the ROM view base addresses address into the hdw accelerators.
|
||||
view[] can be directly or-ed with a relative port address to
|
||||
obtain a valid index in Flash Rom.
|
||||
*/
|
||||
Ce1SetViews;
|
||||
/* Save the ROM view base addresses address into the hdw accelerators.
|
||||
view[] can be directly or-ed with a relative port address to
|
||||
obtain a valid index in Flash Rom.
|
||||
*/
|
||||
Ce1SetViews;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Ce2 module
|
||||
Ce2 module
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -602,13 +570,13 @@ void Ce1Write49(Address rel_address, Nibble datum)
|
|||
the first bank of ERAM.
|
||||
|
||||
.call :
|
||||
Ce2Init49();
|
||||
Ce2Init49();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
3.4, 27-Sep-2000, update:
|
||||
|
@ -616,15 +584,15 @@ void Ce1Write49(Address rel_address, Nibble datum)
|
|||
HP39/40 firmware.
|
||||
|
||||
.- */
|
||||
void Ce2Init49(void)
|
||||
void Ce2Init49( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Init49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Init49" );
|
||||
|
||||
/* Set base of ce2 area */
|
||||
mod_status_49->ce2 = mod_status_49->ram + CE2_RAM_OFFSET;
|
||||
|
||||
/* CE2 always present and write enabled */
|
||||
mod_status.hdw.card_status |= (CE2_CARD_PRESENT|CE2_CARD_WE);
|
||||
mod_status.hdw.card_status |= ( CE2_CARD_PRESENT | CE2_CARD_WE );
|
||||
|
||||
#if 0
|
||||
/* card_status changed; update, set MP bit in HST and post
|
||||
|
@ -635,7 +603,6 @@ void Ce2Init49(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce2Save49
|
||||
|
@ -645,25 +612,24 @@ void Ce2Init49(void)
|
|||
This function saves the status of the Ce2 module.
|
||||
|
||||
.call :
|
||||
Ce2Save49();
|
||||
Ce2Save49();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void Ce2Save49(void)
|
||||
void Ce2Save49( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Save49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Save49" );
|
||||
|
||||
/* Do nothing; the whole RAM is saved by RamSave49() */
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce2Read49
|
||||
|
@ -673,25 +639,24 @@ void Ce2Save49(void)
|
|||
This function reads a nibble from the Ce2 module.
|
||||
|
||||
.call :
|
||||
d = Ce2Read49(rel_address)
|
||||
d = Ce2Read49(rel_address)
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Address rel_address, memory address
|
||||
.output :
|
||||
Nibble *d, datum read from memory
|
||||
Nibble *d, datum read from memory
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
Nibble Ce2Read49(Address rel_address)
|
||||
Nibble Ce2Read49( Address rel_address )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Read49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Read49" );
|
||||
|
||||
return mod_status_49->ce2[rel_address];
|
||||
return mod_status_49->ce2[ rel_address ];
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : Ce2Write49
|
||||
|
@ -701,28 +666,27 @@ Nibble Ce2Read49(Address rel_address)
|
|||
This function writes a nibble to the Ce2 module.
|
||||
|
||||
.call :
|
||||
Ce2Write49(rel_address, datum);
|
||||
Ce2Write49(rel_address, datum);
|
||||
.input :
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
Address rel_address, memory address
|
||||
Nibble datum, datum to be written into memory
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
.- */
|
||||
void Ce2Write49(Address rel_address, Nibble datum)
|
||||
void Ce2Write49( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Write49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Write49" );
|
||||
|
||||
mod_status_49->ce2[rel_address] = datum;
|
||||
mod_status_49->ce2[ rel_address ] = datum;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
NCe3 module
|
||||
NCe3 module
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -735,13 +699,13 @@ void Ce2Write49(Address rel_address, Nibble datum)
|
|||
the first bank of ERAM.
|
||||
|
||||
.call :
|
||||
NCe3Init49();
|
||||
NCe3Init49();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
3.4, 27-Sep-2000, update:
|
||||
|
@ -749,15 +713,15 @@ void Ce2Write49(Address rel_address, Nibble datum)
|
|||
HP39/40 firmware.
|
||||
|
||||
.- */
|
||||
void NCe3Init49(void)
|
||||
void NCe3Init49( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Init49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Init49" );
|
||||
|
||||
/* Set base of nce3 area */
|
||||
mod_status_49->nce3 = mod_status_49->ram + NCE3_RAM_OFFSET;
|
||||
|
||||
/* NCE3 always present and write enabled */
|
||||
mod_status.hdw.card_status |= (NCE3_CARD_PRESENT|NCE3_CARD_WE);
|
||||
mod_status.hdw.card_status |= ( NCE3_CARD_PRESENT | NCE3_CARD_WE );
|
||||
|
||||
#if 0
|
||||
/* card_status changed; update, set MP bit in HST and post
|
||||
|
@ -768,7 +732,6 @@ void NCe3Init49(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : NCe3Save49
|
||||
|
@ -778,25 +741,24 @@ void NCe3Init49(void)
|
|||
This function saves the status of the NCe3 module.
|
||||
|
||||
.call :
|
||||
NCe3Save49();
|
||||
NCe3Save49();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
|
||||
|
||||
.- */
|
||||
void NCe3Save49(void)
|
||||
void NCe3Save49( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Save49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Save49" );
|
||||
|
||||
/* Do nothing; the whole RAM is saved by RamSave49() */
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : NCe3Read49
|
||||
|
@ -814,33 +776,29 @@ void NCe3Save49(void)
|
|||
the ABSOLUTE address of the memory access.
|
||||
|
||||
.call :
|
||||
d = NCe3Read49(rel_address)
|
||||
d = NCe3Read49(rel_address)
|
||||
.input :
|
||||
Address rel_address, memory address (ABSOLUTE)
|
||||
Address rel_address, memory address (ABSOLUTE)
|
||||
.output :
|
||||
Nibble *d, datum read from memory
|
||||
Nibble *d, datum read from memory
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
3.3, 25-Sep-2000, update
|
||||
- added vectors into flash49 for FlashROM read ops
|
||||
|
||||
.- */
|
||||
Nibble NCe3Read49(Address rel_address)
|
||||
Nibble NCe3Read49( Address rel_address )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Read49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Read49" );
|
||||
|
||||
return
|
||||
(mod_status.hdw.hdw[HDW_LCR_OFFSET] & LCR_LED)
|
||||
? FlashRead49(
|
||||
mod_status.hdw.accel.a49.view[
|
||||
(rel_address & FLASH_VIEW_SELECTOR) != 0]
|
||||
| (rel_address & FLASH_BANK_MASK))
|
||||
: mod_status_49->nce3[rel_address & NCE3_RAM_MASK];
|
||||
return ( mod_status.hdw.hdw[ HDW_LCR_OFFSET ] & LCR_LED )
|
||||
? FlashRead49( mod_status.hdw.accel.a49.view[ ( rel_address & FLASH_VIEW_SELECTOR ) != 0 ] |
|
||||
( rel_address & FLASH_BANK_MASK ) )
|
||||
: mod_status_49->nce3[ rel_address & NCE3_RAM_MASK ];
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : NCe3Write49
|
||||
|
@ -859,29 +817,27 @@ Nibble NCe3Read49(Address rel_address)
|
|||
|
||||
|
||||
.call :
|
||||
NCe3Write49(rel_address, datum);
|
||||
NCe3Write49(rel_address, datum);
|
||||
.input :
|
||||
Address rel_address, memory address (ABSOLUTE)
|
||||
Nibble datum, datum to be written into memory
|
||||
Address rel_address, memory address (ABSOLUTE)
|
||||
Nibble datum, datum to be written into memory
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
MOD_I_CALLED
|
||||
MOD_I_CALLED
|
||||
.notes :
|
||||
3.2, 21-Sep-2000, creation
|
||||
3.3, 25-Sep-2000, update
|
||||
- added vectors into flash49 for FlashROM write ops
|
||||
|
||||
.- */
|
||||
void NCe3Write49(Address rel_address, Nibble datum)
|
||||
void NCe3Write49( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Write49");
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Write49" );
|
||||
|
||||
if(mod_status.hdw.hdw[HDW_LCR_OFFSET] & LCR_LED)
|
||||
FlashWrite49(mod_status.hdw.accel.a49.view[
|
||||
(rel_address & FLASH_VIEW_SELECTOR) != 0]
|
||||
| (rel_address & FLASH_BANK_MASK),
|
||||
datum);
|
||||
if ( mod_status.hdw.hdw[ HDW_LCR_OFFSET ] & LCR_LED )
|
||||
FlashWrite49( mod_status.hdw.accel.a49.view[ ( rel_address & FLASH_VIEW_SELECTOR ) != 0 ] | ( rel_address & FLASH_BANK_MASK ),
|
||||
datum );
|
||||
else
|
||||
mod_status_49->nce3[rel_address & NCE3_RAM_MASK] = datum;
|
||||
mod_status_49->nce3[ rel_address & NCE3_RAM_MASK ] = datum;
|
||||
}
|
||||
|
|
938
src/serial.c
938
src/serial.c
File diff suppressed because it is too large
Load diff
81
src/serial.h
81
src/serial.h
|
@ -80,65 +80,62 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macro/Data type definitions
|
||||
Macro/Data type definitions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define SERIAL_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
|
||||
#define SERIAL_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf condition codes
|
||||
Chf condition codes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define SERIAL_I_CALLED 101 /* Function %s called */
|
||||
#define SERIAL_I_REVISION 102 /* Serial port emulation rev. %s */
|
||||
#define SERIAL_I_READ 103 /* Read %s -> %x */
|
||||
#define SERIAL_I_WRITE 104 /* Write %s %x -> %x */
|
||||
#define SERIAL_I_RBR 105 /* Read RBR -> %x */
|
||||
#define SERIAL_I_TBR 106 /* Write TBR <- %x */
|
||||
#define SERIAL_I_PTY_NAME 107 /* Slave pty name is %s */
|
||||
#define SERIAL_W_EMPTY_RRB 201 /* Read from empty RX buffer, rcs=%x */
|
||||
#define SERIAL_W_FULL_TRB 202 /* Write into full TX buffer, tcs=%x */
|
||||
#define SERIAL_W_NOPTY 203 /* 3.16: Pty support not available */
|
||||
#define SERIAL_E_TRB_DRAIN 301 /* Error draining TX buffer */
|
||||
#define SERIAL_E_RRB_CHARGE 302 /* Error charging RX buffer */
|
||||
#define SERIAL_E_PTY_CLOSE 303 /* Error closing pty */
|
||||
#define SERIAL_F_OPENPTY 401 /* openpty() failed on master pty */
|
||||
#define SERIAL_F_FCNTL 402 /* fcntl() failed on master pty */
|
||||
#define SERIAL_F_OPEN_MASTER 403 /* Can't open pty master %s */
|
||||
#define SERIAL_F_GRANTPT 404 /* grantpt() failed on master pty */
|
||||
#define SERIAL_F_UNLOCKPT 405 /* unlockpt() failed on master pty */
|
||||
#define SERIAL_F_OPEN_SLAVE 406 /* Can't open pty slave %s */
|
||||
#define SERIAL_F_PUSH 407 /* ioctl(I_PUSH,%s) failed on slave */
|
||||
#define SERIAL_F_TCGETATTR 408 /* tcgetattr() failed on master */
|
||||
#define SERIAL_F_TCSETATTR 409 /* tcsetattr() failed on master */
|
||||
|
||||
#define SERIAL_I_CALLED 101 /* Function %s called */
|
||||
#define SERIAL_I_REVISION 102 /* Serial port emulation rev. %s */
|
||||
#define SERIAL_I_READ 103 /* Read %s -> %x */
|
||||
#define SERIAL_I_WRITE 104 /* Write %s %x -> %x */
|
||||
#define SERIAL_I_RBR 105 /* Read RBR -> %x */
|
||||
#define SERIAL_I_TBR 106 /* Write TBR <- %x */
|
||||
#define SERIAL_I_PTY_NAME 107 /* Slave pty name is %s */
|
||||
#define SERIAL_W_EMPTY_RRB 201 /* Read from empty RX buffer, rcs=%x */
|
||||
#define SERIAL_W_FULL_TRB 202 /* Write into full TX buffer, tcs=%x */
|
||||
#define SERIAL_W_NOPTY 203 /* 3.16: Pty support not available */
|
||||
#define SERIAL_E_TRB_DRAIN 301 /* Error draining TX buffer */
|
||||
#define SERIAL_E_RRB_CHARGE 302 /* Error charging RX buffer */
|
||||
#define SERIAL_E_PTY_CLOSE 303 /* Error closing pty */
|
||||
#define SERIAL_F_OPENPTY 401 /* openpty() failed on master pty */
|
||||
#define SERIAL_F_FCNTL 402 /* fcntl() failed on master pty */
|
||||
#define SERIAL_F_OPEN_MASTER 403 /* Can't open pty master %s */
|
||||
#define SERIAL_F_GRANTPT 404 /* grantpt() failed on master pty */
|
||||
#define SERIAL_F_UNLOCKPT 405 /* unlockpt() failed on master pty */
|
||||
#define SERIAL_F_OPEN_SLAVE 406 /* Can't open pty slave %s */
|
||||
#define SERIAL_F_PUSH 407 /* ioctl(I_PUSH,%s) failed on slave */
|
||||
#define SERIAL_F_TCGETATTR 408 /* tcgetattr() failed on master */
|
||||
#define SERIAL_F_TCSETATTR 409 /* tcsetattr() failed on master */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Initialization */
|
||||
const char *SerialInit(void);
|
||||
void SerialClose(void);
|
||||
const char* SerialInit( void );
|
||||
void SerialClose( void );
|
||||
|
||||
/* Information about slave side of pty */
|
||||
const char *SerialPtyName(void);
|
||||
const char* SerialPtyName( void );
|
||||
|
||||
/* Register read */
|
||||
Nibble Serial_IOC_Read(void);
|
||||
Nibble Serial_RCS_Read(void);
|
||||
Nibble Serial_TCS_Read(void);
|
||||
int8 Serial_RBR_Read(void);
|
||||
Nibble Serial_IOC_Read( void );
|
||||
Nibble Serial_RCS_Read( void );
|
||||
Nibble Serial_TCS_Read( void );
|
||||
int8 Serial_RBR_Read( void );
|
||||
|
||||
/* Register write */
|
||||
void Serial_IOC_Write(Nibble n);
|
||||
void Serial_RCS_Write(Nibble n);
|
||||
void Serial_TCS_Write(Nibble n);
|
||||
void Serial_CRER_Write(Nibble n);
|
||||
void Serial_TBR_Write(int8 d);
|
||||
void Serial_IOC_Write( Nibble n );
|
||||
void Serial_RCS_Write( Nibble n );
|
||||
void Serial_TCS_Write( Nibble n );
|
||||
void Serial_CRER_Write( Nibble n );
|
||||
void Serial_TBR_Write( int8 d );
|
||||
|
||||
/* Event handling */
|
||||
void HandleSerial(void);
|
||||
void HandleSerial( void );
|
||||
|
|
721
src/t48.c
721
src/t48.c
|
@ -87,391 +87,395 @@ static char rcs_id[] = "$Id: t48.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
#include "args.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID X11_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID X11_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf parameters - Do not change.
|
||||
The ABNORMAL_EXIT_CODE is taken from stdlib.h (EXIT_FAILURE)
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define MAIN_MSGCAT_NAME "t48.cat"
|
||||
#define CONDITION_STACK_SIZE 16
|
||||
#define HANDLER_STACK_SIZE 8
|
||||
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
||||
|
||||
#define MAIN_MSGCAT_NAME "t48.cat"
|
||||
#define CONDITION_STACK_SIZE 16
|
||||
#define HANDLER_STACK_SIZE 8
|
||||
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Other parameters
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define APP_CLASS "T48"
|
||||
#define LCD_BACKGROUND "green"
|
||||
#define LCD_FOREGROUND "black"
|
||||
|
||||
#define APP_CLASS "T48"
|
||||
#define LCD_BACKGROUND "green"
|
||||
#define LCD_FOREGROUND "black"
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private variables
|
||||
Private variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
static XtAppContext app_context;
|
||||
static Widget shell_widget;
|
||||
|
||||
/* Command line options descriptor */
|
||||
XrmOptionDescRec options[] =
|
||||
{
|
||||
/* option, specifier, argKind, value */
|
||||
{ "-reset", "*reset", XrmoptionNoArg, "True" },
|
||||
{ "-monitor", "*monitor", XrmoptionNoArg, "True" },
|
||||
{ "-path", "*path", XrmoptionSepArg },
|
||||
{ "-cpu", "*cpu", XrmoptionSepArg },
|
||||
{ "-mod", "*mod", XrmoptionSepArg },
|
||||
{ "-hdw", "*hdw", XrmoptionSepArg },
|
||||
{ "-rom", "*rom", XrmoptionSepArg },
|
||||
{ "-ram", "*ram", XrmoptionSepArg },
|
||||
{ "-port1", "*port1", XrmoptionSepArg },
|
||||
{ "-port2", "*port2", XrmoptionSepArg }
|
||||
XrmOptionDescRec options[] = {
|
||||
/* option, specifier, argKind, value */
|
||||
{ "-reset", "*reset", XrmoptionNoArg, "True" },
|
||||
{ "-monitor", "*monitor", XrmoptionNoArg, "True" },
|
||||
{ "-path", "*path", XrmoptionSepArg },
|
||||
{ "-cpu", "*cpu", XrmoptionSepArg },
|
||||
{ "-mod", "*mod", XrmoptionSepArg },
|
||||
{ "-hdw", "*hdw", XrmoptionSepArg },
|
||||
{ "-rom", "*rom", XrmoptionSepArg },
|
||||
{ "-ram", "*ram", XrmoptionSepArg },
|
||||
{ "-port1", "*port1", XrmoptionSepArg },
|
||||
{ "-port2", "*port2", XrmoptionSepArg }
|
||||
};
|
||||
|
||||
#define NUM_OPTIONS (sizeof(options)/sizeof(XrmOptionDescRec))
|
||||
|
||||
#define NUM_OPTIONS ( sizeof( options ) / sizeof( XrmOptionDescRec ) )
|
||||
|
||||
/* Application fallback resources */
|
||||
String fallback_resources[] =
|
||||
{
|
||||
NULL /* Null terminated */
|
||||
String fallback_resources[] = {
|
||||
NULL /* Null terminated */
|
||||
};
|
||||
|
||||
|
||||
/* Application options container */
|
||||
struct app_opt
|
||||
{
|
||||
Boolean reset;
|
||||
Boolean monitor;
|
||||
Pixel fg_pix;
|
||||
Pixel bg_pix;
|
||||
String path;
|
||||
String cpu;
|
||||
String mod;
|
||||
String hdw;
|
||||
String rom;
|
||||
String ram;
|
||||
String port1;
|
||||
String port2;
|
||||
struct app_opt {
|
||||
Boolean reset;
|
||||
Boolean monitor;
|
||||
Pixel fg_pix;
|
||||
Pixel bg_pix;
|
||||
String path;
|
||||
String cpu;
|
||||
String mod;
|
||||
String hdw;
|
||||
String rom;
|
||||
String ram;
|
||||
String port1;
|
||||
String port2;
|
||||
};
|
||||
|
||||
|
||||
/* Application resources/options descriptor */
|
||||
XtResource app_res[] =
|
||||
{
|
||||
{ "foreground", "Foreground",
|
||||
XtRPixel, sizeof(Pixel), XtOffsetOf(struct app_opt, fg_pix),
|
||||
XtRString, LCD_FOREGROUND
|
||||
},
|
||||
{ "background", "Background",
|
||||
XtRPixel, sizeof(Pixel), XtOffsetOf(struct app_opt, bg_pix),
|
||||
XtRString, LCD_BACKGROUND
|
||||
},
|
||||
{ "reset", "Reset",
|
||||
XtRBoolean, sizeof(Boolean), XtOffsetOf(struct app_opt, reset),
|
||||
XtRString, "False"
|
||||
},
|
||||
{ "monitor", "Monitor",
|
||||
XtRBoolean, sizeof(Boolean), XtOffsetOf(struct app_opt, monitor),
|
||||
XtRString, "False"
|
||||
},
|
||||
{ "path", "Path",
|
||||
XtRString, sizeof(String), XtOffsetOf(struct app_opt, path),
|
||||
XtRString, "."
|
||||
},
|
||||
{ "cpu", "Cpu",
|
||||
XtRString, sizeof(String), XtOffsetOf(struct app_opt, cpu),
|
||||
XtRString, "cpu"
|
||||
},
|
||||
{ "mod", "Mod",
|
||||
XtRString, sizeof(String), XtOffsetOf(struct app_opt, mod),
|
||||
XtRString, "mod"
|
||||
},
|
||||
{ "hdw", "Hdw",
|
||||
XtRString, sizeof(String), XtOffsetOf(struct app_opt, hdw),
|
||||
XtRString, "hdw"
|
||||
},
|
||||
{ "rom", "Rom",
|
||||
XtRString, sizeof(String), XtOffsetOf(struct app_opt, rom),
|
||||
XtRString, "rom"
|
||||
},
|
||||
{ "ram", "Ram",
|
||||
XtRString, sizeof(String), XtOffsetOf(struct app_opt, ram),
|
||||
XtRString, "ram"
|
||||
},
|
||||
{ "port1", "Port1",
|
||||
XtRString, sizeof(String), XtOffsetOf(struct app_opt, port1),
|
||||
XtRString, "port1"
|
||||
},
|
||||
{ "port2", "Port2",
|
||||
XtRString, sizeof(String), XtOffsetOf(struct app_opt, port2),
|
||||
XtRString, "port2"
|
||||
}
|
||||
XtResource app_res[] = {
|
||||
{"foreground", "Foreground", XtRPixel, sizeof( Pixel ), XtOffsetOf( struct app_opt, fg_pix ), XtRString, LCD_FOREGROUND},
|
||||
{"background", "Background", XtRPixel, sizeof( Pixel ), XtOffsetOf( struct app_opt, bg_pix ), XtRString, LCD_BACKGROUND},
|
||||
{"reset", "Reset", XtRBoolean, sizeof( Boolean ), XtOffsetOf( struct app_opt, reset ), XtRString, "False" },
|
||||
{"monitor", "Monitor", XtRBoolean, sizeof( Boolean ), XtOffsetOf( struct app_opt, monitor ), XtRString, "False" },
|
||||
{"path", "Path", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, path ), XtRString, "." },
|
||||
{"cpu", "Cpu", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, cpu ), XtRString, "cpu" },
|
||||
{"mod", "Mod", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, mod ), XtRString, "mod" },
|
||||
{"hdw", "Hdw", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, hdw ), XtRString, "hdw" },
|
||||
{"rom", "Rom", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, rom ), XtRString, "rom" },
|
||||
{"ram", "Ram", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, ram ), XtRString, "ram" },
|
||||
{"port1", "Port1", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, port1 ), XtRString, "port1" },
|
||||
{"port2", "Port2", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, port2 ), XtRString, "port2" }
|
||||
};
|
||||
|
||||
#define NUM_APP_RES (sizeof(app_res)/sizeof(XtResource))
|
||||
|
||||
#define NUM_APP_RES ( sizeof( app_res ) / sizeof( XtResource ) )
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public variables
|
||||
Public variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Emulator options */
|
||||
struct Args args;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private functions
|
||||
Private functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* KeySym -> HP48 'enum Key' translator */
|
||||
static enum Key Ks2K(KeySym ks)
|
||||
static enum Key Ks2K( KeySym ks )
|
||||
{
|
||||
switch(ks)
|
||||
{
|
||||
/* Backspace */
|
||||
case XK_BackSpace: return KEY_BKSP;
|
||||
switch ( ks ) {
|
||||
/* Backspace */
|
||||
case XK_BackSpace:
|
||||
return KEY_BKSP;
|
||||
|
||||
/* Delete */
|
||||
case XK_Delete: return KEY_DEL;
|
||||
case XK_KP_Delete: return KEY_DEL;
|
||||
/* Delete */
|
||||
case XK_Delete:
|
||||
return KEY_DEL;
|
||||
case XK_KP_Delete:
|
||||
return KEY_DEL;
|
||||
|
||||
/* Enter */
|
||||
case XK_KP_Enter: return KEY_ENTER;
|
||||
case XK_Return: return KEY_ENTER;
|
||||
/* Enter */
|
||||
case XK_KP_Enter:
|
||||
return KEY_ENTER;
|
||||
case XK_Return:
|
||||
return KEY_ENTER;
|
||||
|
||||
/* Cursor keys */
|
||||
case XK_KP_Left: return KEY_LEFT;
|
||||
case XK_Left: return KEY_LEFT;
|
||||
/* Cursor keys */
|
||||
case XK_KP_Left:
|
||||
return KEY_LEFT;
|
||||
case XK_Left:
|
||||
return KEY_LEFT;
|
||||
|
||||
case XK_KP_Right: return KEY_RIGHT;
|
||||
case XK_Right: return KEY_RIGHT;
|
||||
case XK_KP_Right:
|
||||
return KEY_RIGHT;
|
||||
case XK_Right:
|
||||
return KEY_RIGHT;
|
||||
|
||||
case XK_KP_Up: return KEY_UP;
|
||||
case XK_Up: return KEY_UP;
|
||||
case XK_KP_Up:
|
||||
return KEY_UP;
|
||||
case XK_Up:
|
||||
return KEY_UP;
|
||||
|
||||
case XK_KP_Down: return KEY_DOWN;
|
||||
case XK_Down: return KEY_DOWN;
|
||||
case XK_KP_Down:
|
||||
return KEY_DOWN;
|
||||
case XK_Down:
|
||||
return KEY_DOWN;
|
||||
|
||||
/* Function keys */
|
||||
case XK_F1: return KEY_F1;
|
||||
case XK_F2: return KEY_F2;
|
||||
case XK_F3: return KEY_F3;
|
||||
case XK_F4: return KEY_F4;
|
||||
case XK_F5: return KEY_F5;
|
||||
case XK_F6: return KEY_F6;
|
||||
/* Function keys */
|
||||
case XK_F1:
|
||||
return KEY_F1;
|
||||
case XK_F2:
|
||||
return KEY_F2;
|
||||
case XK_F3:
|
||||
return KEY_F3;
|
||||
case XK_F4:
|
||||
return KEY_F4;
|
||||
case XK_F5:
|
||||
return KEY_F5;
|
||||
case XK_F6:
|
||||
return KEY_F6;
|
||||
|
||||
/* Shift L, R, Alpha, ON */
|
||||
case XK_Shift_L: return KEY_SH_L;
|
||||
case XK_Shift_R: return KEY_SH_R;
|
||||
case XK_Alt_L: return KEY_ALPHA;
|
||||
case XK_Alt_R: return KEY_ALPHA;
|
||||
case XK_Escape: return KEY_ON;
|
||||
/* Shift L, R, Alpha, ON */
|
||||
case XK_Shift_L:
|
||||
return KEY_SH_L;
|
||||
case XK_Shift_R:
|
||||
return KEY_SH_R;
|
||||
case XK_Alt_L:
|
||||
return KEY_ALPHA;
|
||||
case XK_Alt_R:
|
||||
return KEY_ALPHA;
|
||||
case XK_Escape:
|
||||
return KEY_ON;
|
||||
|
||||
/* Numeric keypad and surroundings */
|
||||
case XK_KP_0: return KEY_0;
|
||||
case XK_KP_1: return KEY_1;
|
||||
case XK_KP_2: return KEY_2;
|
||||
case XK_KP_3: return KEY_3;
|
||||
case XK_KP_4: return KEY_4;
|
||||
case XK_KP_5: return KEY_5;
|
||||
case XK_KP_6: return KEY_6;
|
||||
case XK_KP_7: return KEY_7;
|
||||
case XK_KP_8: return KEY_8;
|
||||
case XK_KP_9: return KEY_9;
|
||||
/* Numeric keypad and surroundings */
|
||||
case XK_KP_0:
|
||||
return KEY_0;
|
||||
case XK_KP_1:
|
||||
return KEY_1;
|
||||
case XK_KP_2:
|
||||
return KEY_2;
|
||||
case XK_KP_3:
|
||||
return KEY_3;
|
||||
case XK_KP_4:
|
||||
return KEY_4;
|
||||
case XK_KP_5:
|
||||
return KEY_5;
|
||||
case XK_KP_6:
|
||||
return KEY_6;
|
||||
case XK_KP_7:
|
||||
return KEY_7;
|
||||
case XK_KP_8:
|
||||
return KEY_8;
|
||||
case XK_KP_9:
|
||||
return KEY_9;
|
||||
|
||||
case XK_KP_Decimal: return KEY_DOT;
|
||||
case XK_KP_Decimal:
|
||||
return KEY_DOT;
|
||||
|
||||
case XK_KP_Add: return KEY_ADD;
|
||||
case XK_plus: return KEY_ADD;
|
||||
case XK_KP_Add:
|
||||
return KEY_ADD;
|
||||
case XK_plus:
|
||||
return KEY_ADD;
|
||||
|
||||
case XK_KP_Subtract: return KEY_SUB;
|
||||
case XK_minus: return KEY_SUB;
|
||||
case XK_KP_Subtract:
|
||||
return KEY_SUB;
|
||||
case XK_minus:
|
||||
return KEY_SUB;
|
||||
|
||||
case XK_KP_Multiply: return KEY_MUL;
|
||||
case XK_asterisk: return KEY_MUL;
|
||||
case XK_KP_Multiply:
|
||||
return KEY_MUL;
|
||||
case XK_asterisk:
|
||||
return KEY_MUL;
|
||||
|
||||
case XK_KP_Divide: return KEY_DIV;
|
||||
case XK_slash: return KEY_DIV;
|
||||
case XK_KP_Divide:
|
||||
return KEY_DIV;
|
||||
case XK_slash:
|
||||
return KEY_DIV;
|
||||
|
||||
case XK_KP_Space: return KEY_SPC;
|
||||
case XK_space: return KEY_SPC;
|
||||
case XK_KP_Space:
|
||||
return KEY_SPC;
|
||||
case XK_space:
|
||||
return KEY_SPC;
|
||||
|
||||
/* Upper half of the keyboard */
|
||||
case XK_1: return KEY_MTH;
|
||||
case XK_2: return KEY_PRG;
|
||||
case XK_3: return KEY_CST;
|
||||
case XK_4: return KEY_VAR;
|
||||
case XK_5: return KEY_UP;
|
||||
case XK_6: return KEY_NXT;
|
||||
/* Upper half of the keyboard */
|
||||
case XK_1:
|
||||
return KEY_MTH;
|
||||
case XK_2:
|
||||
return KEY_PRG;
|
||||
case XK_3:
|
||||
return KEY_CST;
|
||||
case XK_4:
|
||||
return KEY_VAR;
|
||||
case XK_5:
|
||||
return KEY_UP;
|
||||
case XK_6:
|
||||
return KEY_NXT;
|
||||
|
||||
case XK_q: return KEY_AP;
|
||||
case XK_w: return KEY_STO;
|
||||
case XK_e: return KEY_EVAL;
|
||||
case XK_r: return KEY_LEFT;
|
||||
case XK_t: return KEY_DOWN;
|
||||
case XK_y: return KEY_RIGHT;
|
||||
case XK_q:
|
||||
return KEY_AP;
|
||||
case XK_w:
|
||||
return KEY_STO;
|
||||
case XK_e:
|
||||
return KEY_EVAL;
|
||||
case XK_r:
|
||||
return KEY_LEFT;
|
||||
case XK_t:
|
||||
return KEY_DOWN;
|
||||
case XK_y:
|
||||
return KEY_RIGHT;
|
||||
|
||||
case XK_a: return KEY_SIN;
|
||||
case XK_s: return KEY_COS;
|
||||
case XK_d: return KEY_TAN;
|
||||
case XK_f: return KEY_SQRT;
|
||||
case XK_g: return KEY_POWER;
|
||||
case XK_h: return KEY_INV;
|
||||
case XK_a:
|
||||
return KEY_SIN;
|
||||
case XK_s:
|
||||
return KEY_COS;
|
||||
case XK_d:
|
||||
return KEY_TAN;
|
||||
case XK_f:
|
||||
return KEY_SQRT;
|
||||
case XK_g:
|
||||
return KEY_POWER;
|
||||
case XK_h:
|
||||
return KEY_INV;
|
||||
|
||||
case XK_z: return KEY_ENTER;
|
||||
case XK_x: return KEY_ENTER;
|
||||
case XK_c: return KEY_CHS;
|
||||
case XK_v: return KEY_EEX;
|
||||
case XK_b: return KEY_DEL;
|
||||
case XK_n: return KEY_BKSP;
|
||||
case XK_z:
|
||||
return KEY_ENTER;
|
||||
case XK_x:
|
||||
return KEY_ENTER;
|
||||
case XK_c:
|
||||
return KEY_CHS;
|
||||
case XK_v:
|
||||
return KEY_EEX;
|
||||
case XK_b:
|
||||
return KEY_DEL;
|
||||
case XK_n:
|
||||
return KEY_BKSP;
|
||||
|
||||
/* Other useful aliases */
|
||||
case XK_Tab: return KEY_NXT;
|
||||
case XK_apostrophe: return KEY_AP;
|
||||
case XK_period: return KEY_DOT;
|
||||
/* Other useful aliases */
|
||||
case XK_Tab:
|
||||
return KEY_NXT;
|
||||
case XK_apostrophe:
|
||||
return KEY_AP;
|
||||
case XK_period:
|
||||
return KEY_DOT;
|
||||
|
||||
/* Save */
|
||||
case XK_Control_L:
|
||||
ModSave();
|
||||
CpuSave();
|
||||
exit(0);
|
||||
}
|
||||
/* Save */
|
||||
case XK_Control_L:
|
||||
ModSave();
|
||||
CpuSave();
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
return KEY_NULL;
|
||||
return KEY_NULL;
|
||||
}
|
||||
|
||||
|
||||
/* X Event handler, called by the X Toolkit when appropriate */
|
||||
static void XEventHandler(Widget w, XtPointer cl_data, XEvent *ev,
|
||||
Boolean *cont)
|
||||
static void XEventHandler( Widget w, XtPointer cl_data, XEvent* ev, Boolean* cont )
|
||||
{
|
||||
KeySym ks;
|
||||
KeySym ks;
|
||||
|
||||
debug1(DEBUG_C_TRACE|DEBUG_C_X11, X11_I_CALLED, "XEventHandler");
|
||||
debug1( DEBUG_C_TRACE | DEBUG_C_X11, X11_I_CALLED, "XEventHandler" );
|
||||
|
||||
/* Continue to dispatch */
|
||||
*cont = True;
|
||||
/* Continue to dispatch */
|
||||
*cont = True;
|
||||
|
||||
if(ev->type == Expose)
|
||||
{
|
||||
debug1(DEBUG_C_X11, X11_I_LCD_EXPOSE, ev->xexpose.count);
|
||||
if(ev->xexpose.count == 0) RefreshLcd();
|
||||
}
|
||||
|
||||
else if(ev->type == KeyPress || ev->type == KeyRelease)
|
||||
{
|
||||
(void)XLookupString((XKeyEvent *)ev, (char *)NULL, 0, &ks,
|
||||
(XComposeStatus *)NULL);
|
||||
|
||||
if(ev->type == KeyPress)
|
||||
{
|
||||
debug1(DEBUG_C_X11, X11_I_KEY_PRESS, ks);
|
||||
KeybPress(Ks2K(ks));
|
||||
if ( ev->type == Expose ) {
|
||||
debug1( DEBUG_C_X11, X11_I_LCD_EXPOSE, ev->xexpose.count );
|
||||
if ( ev->xexpose.count == 0 )
|
||||
RefreshLcd();
|
||||
}
|
||||
|
||||
else if(ev->type = KeyRelease)
|
||||
{
|
||||
debug1(DEBUG_C_X11, X11_I_KEY_RELEASE, ks);
|
||||
KeybRelease(Ks2K(ks));
|
||||
}
|
||||
}
|
||||
else if ( ev->type == KeyPress || ev->type == KeyRelease ) {
|
||||
( void )XLookupString( ( XKeyEvent* )ev, ( char* )NULL, 0, &ks, ( XComposeStatus* )NULL );
|
||||
|
||||
else
|
||||
{
|
||||
/* Unknown X Event - discard */
|
||||
debug1(DEBUG_C_X11, X11_I_X_EVENT, ev->type);
|
||||
}
|
||||
if ( ev->type == KeyPress ) {
|
||||
debug1( DEBUG_C_X11, X11_I_KEY_PRESS, ks );
|
||||
KeybPress( Ks2K( ks ) );
|
||||
}
|
||||
|
||||
else if ( ev->type = KeyRelease ) {
|
||||
debug1( DEBUG_C_X11, X11_I_KEY_RELEASE, ks );
|
||||
KeybRelease( Ks2K( ks ) );
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
/* Unknown X Event - discard */
|
||||
debug1( DEBUG_C_X11, X11_I_X_EVENT, ev->type );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Path/name dynamic allocator */
|
||||
static char *GetPathname(String path, String name)
|
||||
static char* GetPathname( String path, String name )
|
||||
{
|
||||
char *s = malloc(strlen(path)+strlen(name)+2);
|
||||
char* s = malloc( strlen( path ) + strlen( name ) + 2 );
|
||||
|
||||
strcpy(s, path); strcat(s, "/"); strcat(s, name);
|
||||
return s;
|
||||
strcpy( s, path );
|
||||
strcat( s, "/" );
|
||||
strcat( s, name );
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the X interface */
|
||||
void InitializeX(int argc, char *argv[], struct app_opt *opt)
|
||||
void InitializeX( int argc, char* argv[], struct app_opt* opt )
|
||||
{
|
||||
unsigned long fg_pix, bg_pix;
|
||||
XSetWindowAttributes attr;
|
||||
Arg xt_args[20];
|
||||
int n;
|
||||
unsigned long fg_pix, bg_pix;
|
||||
XSetWindowAttributes attr;
|
||||
Arg xt_args[ 20 ];
|
||||
int n;
|
||||
|
||||
debug1(DEBUG_C_TRACE, X11_I_CALLED, "InitializeX");
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "InitializeX" );
|
||||
|
||||
/* Setup Arg vector for shell widget creation */
|
||||
n = 0;
|
||||
XtSetArg(xt_args[n], XtNwidth, 131*2+2*8); n++;
|
||||
XtSetArg(xt_args[n], XtNminWidth, 131*2+2*8); n++;
|
||||
XtSetArg(xt_args[n], XtNmaxWidth, 131*2+2*8); n++;
|
||||
XtSetArg(xt_args[n], XtNheight, 64*2+28); n++;
|
||||
XtSetArg(xt_args[n], XtNminHeight, 64*2+28); n++;
|
||||
XtSetArg(xt_args[n], XtNmaxHeight, 64*2+28); n++;
|
||||
XtSetArg(xt_args[n], XtNx, 0); n++;
|
||||
XtSetArg(xt_args[n], XtNy, 0); n++;
|
||||
XtSetArg(xt_args[n], XtNinput, True); n++;
|
||||
/* Setup Arg vector for shell widget creation */
|
||||
n = 0;
|
||||
XtSetArg( xt_args[ n ], XtNwidth, 131 * 2 + 2 * 8 );
|
||||
n++;
|
||||
XtSetArg( xt_args[ n ], XtNminWidth, 131 * 2 + 2 * 8 );
|
||||
n++;
|
||||
XtSetArg( xt_args[ n ], XtNmaxWidth, 131 * 2 + 2 * 8 );
|
||||
n++;
|
||||
XtSetArg( xt_args[ n ], XtNheight, 64 * 2 + 28 );
|
||||
n++;
|
||||
XtSetArg( xt_args[ n ], XtNminHeight, 64 * 2 + 28 );
|
||||
n++;
|
||||
XtSetArg( xt_args[ n ], XtNmaxHeight, 64 * 2 + 28 );
|
||||
n++;
|
||||
XtSetArg( xt_args[ n ], XtNx, 0 );
|
||||
n++;
|
||||
XtSetArg( xt_args[ n ], XtNy, 0 );
|
||||
n++;
|
||||
XtSetArg( xt_args[ n ], XtNinput, True );
|
||||
n++;
|
||||
|
||||
/* Initialize application, parse command line options,
|
||||
create its main shell.
|
||||
*/
|
||||
shell_widget = XtAppInitialize(
|
||||
&app_context,
|
||||
APP_CLASS,
|
||||
options, NUM_OPTIONS,
|
||||
&argc, argv,
|
||||
fallback_resources,
|
||||
xt_args, n
|
||||
);
|
||||
/* Initialize application, parse command line options,
|
||||
create its main shell.
|
||||
*/
|
||||
shell_widget = XtAppInitialize( &app_context, APP_CLASS, options, NUM_OPTIONS, &argc, argv, fallback_resources, xt_args, n );
|
||||
|
||||
/* Check unknown options - argv[0] always contains program name */
|
||||
if(argc > 1)
|
||||
{
|
||||
int i;
|
||||
for(i=1; i<argc; i++)
|
||||
ChfCondition X11_E_BAD_OPTION, CHF_ERROR, argv[i] ChfEnd;
|
||||
/* Check unknown options - argv[0] always contains program name */
|
||||
if ( argc > 1 ) {
|
||||
int i;
|
||||
for ( i = 1; i < argc; i++ )
|
||||
ChfCondition X11_E_BAD_OPTION, CHF_ERROR, argv[ i ] ChfEnd;
|
||||
|
||||
ChfCondition X11_I_USAGE, CHF_INFO, argv[0] ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Get application options and fill the 'struct app_opt opt' structure */
|
||||
XtGetApplicationResources(
|
||||
shell_widget,
|
||||
(XtPointer)opt,
|
||||
app_res,
|
||||
NUM_APP_RES,
|
||||
(ArgList)NULL,
|
||||
(Cardinal)0
|
||||
);
|
||||
ChfCondition X11_I_USAGE, CHF_INFO, argv[ 0 ] ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Add private event handler for the main shell */
|
||||
XtAddEventHandler(
|
||||
shell_widget,
|
||||
KeyPressMask|KeyReleaseMask|ExposureMask,
|
||||
False, /* Don't call with non-maskable events */
|
||||
XEventHandler,
|
||||
(XtPointer)NULL
|
||||
);
|
||||
/* Get application options and fill the 'struct app_opt opt' structure */
|
||||
XtGetApplicationResources( shell_widget, ( XtPointer )opt, app_res, NUM_APP_RES, ( ArgList )NULL, ( Cardinal )0 );
|
||||
|
||||
/* Realize shell widget */
|
||||
XtRealizeWidget(shell_widget);
|
||||
/* Add private event handler for the main shell */
|
||||
XtAddEventHandler( shell_widget, KeyPressMask | KeyReleaseMask | ExposureMask, False, /* Don't call with non-maskable events */
|
||||
XEventHandler, ( XtPointer )NULL );
|
||||
|
||||
/* Realize shell widget */
|
||||
XtRealizeWidget( shell_widget );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -484,41 +488,40 @@ void InitializeX(int argc, char *argv[], struct app_opt *opt)
|
|||
It must handle the X Events relevant for the application.
|
||||
|
||||
.call :
|
||||
HandleXEvents();
|
||||
HandleXEvents();
|
||||
.input :
|
||||
void
|
||||
void
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
X11_I_LCD_EXPOSE
|
||||
X11_I_KEY_PRESS
|
||||
X11_I_KEY_RELEASE
|
||||
X11_I_X_EVENT
|
||||
X11_I_CALLED
|
||||
X11_I_LCD_EXPOSE
|
||||
X11_I_KEY_PRESS
|
||||
X11_I_KEY_RELEASE
|
||||
X11_I_X_EVENT
|
||||
.notes :
|
||||
1.1, 19-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void HandleXEvents(void)
|
||||
void HandleXEvents( void )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, X11_I_CALLED, "HandleXEvents");
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "HandleXEvents" );
|
||||
|
||||
/* If there is at least one event pending, process the first event.
|
||||
NOTE: This is an IF instead of a WHILE for two reasons:
|
||||
/* If there is at least one event pending, process the first event.
|
||||
NOTE: This is an IF instead of a WHILE for two reasons:
|
||||
|
||||
- to be sure that X Events related to the keyboard interface are
|
||||
actually 'seen' by the HP48, since the current keyboard emulator
|
||||
has no key memory.
|
||||
- to be sure that X Events related to the keyboard interface are
|
||||
actually 'seen' by the HP48, since the current keyboard emulator
|
||||
has no key memory.
|
||||
|
||||
- this function will be called again very soon, so the Events queue
|
||||
will not starve anyway.
|
||||
*/
|
||||
|
||||
if(XtAppPending(app_context))
|
||||
XtAppProcessEvent(app_context, XtIMAll);
|
||||
- this function will be called again very soon, so the Events queue
|
||||
will not starve anyway.
|
||||
*/
|
||||
|
||||
if ( XtAppPending( app_context ) )
|
||||
XtAppProcessEvent( app_context, XtIMAll );
|
||||
}
|
||||
|
||||
|
||||
/* .+
|
||||
|
||||
.title : main
|
||||
|
@ -531,66 +534,60 @@ void HandleXEvents(void)
|
|||
1.1, 19-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
int main(int argc, char *argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
struct app_opt opt;
|
||||
struct app_opt opt;
|
||||
|
||||
/* Chf initialization with msgcat subsystem */
|
||||
if(ChfMsgcatInit(
|
||||
argv[0], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
MAIN_MSGCAT_NAME, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||
) != CHF_S_OK)
|
||||
{
|
||||
fprintf(stderr, "Chf initialization failed\n");
|
||||
exit(ABNORMAL_EXIT_CODE);
|
||||
}
|
||||
/* Chf initialization with msgcat subsystem */
|
||||
if ( ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
MAIN_MSGCAT_NAME, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||
) != CHF_S_OK ) {
|
||||
fprintf( stderr, "Chf initialization failed\n" );
|
||||
exit( ABNORMAL_EXIT_CODE );
|
||||
}
|
||||
|
||||
debug1(DEBUG_C_TRACE|DEBUG_C_REVISION, X11_I_REVISION, "$Id: t48.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $");
|
||||
debug1( DEBUG_C_TRACE | DEBUG_C_REVISION, X11_I_REVISION, "$Id: t48.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $" );
|
||||
|
||||
/* Initialize X */
|
||||
InitializeX(argc, argv, &opt);
|
||||
/* Initialize X */
|
||||
InitializeX( argc, argv, &opt );
|
||||
|
||||
/* Initialize LCD window */
|
||||
InitLcd(XtDisplay(shell_widget), XtWindow(shell_widget),
|
||||
opt.fg_pix, opt.bg_pix);
|
||||
/* Initialize LCD window */
|
||||
InitLcd( XtDisplay( shell_widget ), XtWindow( shell_widget ), opt.fg_pix, opt.bg_pix );
|
||||
|
||||
/* Fill the emulator options data structure */
|
||||
args.cpu_file_name = GetPathname(opt.path, opt.cpu);
|
||||
args.mod_file_name = GetPathname(opt.path, opt.mod);
|
||||
args.hdw_file_name = GetPathname(opt.path, opt.hdw);
|
||||
args.rom_file_name = GetPathname(opt.path, opt.rom);
|
||||
args.ram_file_name = GetPathname(opt.path, opt.ram);
|
||||
args.port_1_file_name = GetPathname(opt.path, opt.port1);
|
||||
args.port_2_file_name = GetPathname(opt.path, opt.port2);
|
||||
/* Fill the emulator options data structure */
|
||||
args.cpu_file_name = GetPathname( opt.path, opt.cpu );
|
||||
args.mod_file_name = GetPathname( opt.path, opt.mod );
|
||||
args.hdw_file_name = GetPathname( opt.path, opt.hdw );
|
||||
args.rom_file_name = GetPathname( opt.path, opt.rom );
|
||||
args.ram_file_name = GetPathname( opt.path, opt.ram );
|
||||
args.port_1_file_name = GetPathname( opt.path, opt.port1 );
|
||||
args.port_2_file_name = GetPathname( opt.path, opt.port2 );
|
||||
|
||||
/* Initialize peripheral modules */
|
||||
ModInit();
|
||||
/* Initialize peripheral modules */
|
||||
ModInit();
|
||||
|
||||
/* Initialize peripheral modules */
|
||||
CpuInit();
|
||||
/* Initialize peripheral modules */
|
||||
CpuInit();
|
||||
|
||||
/* Reset the system, if required */
|
||||
if(opt.reset)
|
||||
{
|
||||
ModReset();
|
||||
CpuReset();
|
||||
}
|
||||
/* Reset the system, if required */
|
||||
if ( opt.reset ) {
|
||||
ModReset();
|
||||
CpuReset();
|
||||
}
|
||||
|
||||
if(opt.monitor)
|
||||
{
|
||||
/* Call Monitor */
|
||||
Monitor();
|
||||
}
|
||||
if ( opt.monitor ) {
|
||||
/* Call Monitor */
|
||||
Monitor();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Call Emulator directly */
|
||||
Emulator();
|
||||
}
|
||||
else {
|
||||
/* Call Emulator directly */
|
||||
Emulator();
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
69
src/x11.h
69
src/x11.h
|
@ -101,57 +101,52 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macro/Data type definitions
|
||||
Macro/Data type definitions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define X11_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
|
||||
|
||||
typedef void (*FsbContinuation)(int proceed, char *file_name);
|
||||
#define X11_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
|
||||
typedef void ( *FsbContinuation )( int proceed, char* file_name );
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Global variables
|
||||
Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf condition codes
|
||||
Chf condition codes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define X11_I_CALLED 101 /* Function %s called */
|
||||
#define X11_I_LCD_PAR 102 /* LCD Parameter %s: %x */
|
||||
#define X11_I_LCD_EXPOSE 103 /* LCD X Expose event, count=%d */
|
||||
#define X11_I_KEY_PRESS 104 /* 2.1: Pressed key %s */
|
||||
#define X11_I_KEY_RELEASE 105 /* 2.1: Released key %s */
|
||||
#define X11_I_REVISION 107 /* X11 interface revision: %s */
|
||||
#define X11_I_USAGE 108 /* Usage %s: ... */
|
||||
#define X11_I_FACE 109 /* Selected face %s */
|
||||
#define X11_I_NKEYS 110 /* The face has %d keys */
|
||||
#define X11_I_KEY 111 /* Creating key %d, inOut %s */
|
||||
#define X11_I_FOUND_CS 112 /* Found cs widget %s, value %s */
|
||||
#define X11_I_HIER 113 /* Traversing widget %s */
|
||||
#define X11_I_HIER_NC 114 /* Current widget has %d children */
|
||||
#define X11_W_BAD_ACTION_CALL 201 /* Xt Action called with %d args */
|
||||
#define X11_W_UNKNOWN_ATOM 202 /* X Atom %s unknown */
|
||||
#define X11_W_NO_FSB_CONT 203 /* 3.13: FSB continuation not set */
|
||||
#define X11_W_TOO_MANY_MSG 204 /* 3.15: Too many messages (max %d) */
|
||||
#define X11_E_BAD_OPTION 301 /* Invalid option: %s */
|
||||
#define X11_E_NO_WM_COMMAND 302 /* WM_COMMAND property bad/not set */
|
||||
#define X11_E_NO_FSB_TSEG 303 /* 3.13: No txt seg in fsb XmString */
|
||||
#define X11_F_X_ERROR 401 /* X Window System fatal error */
|
||||
#define X11_F_NO_KEYS 402 /* 3.15: Face has no keys */
|
||||
|
||||
#define X11_I_CALLED 101 /* Function %s called */
|
||||
#define X11_I_LCD_PAR 102 /* LCD Parameter %s: %x */
|
||||
#define X11_I_LCD_EXPOSE 103 /* LCD X Expose event, count=%d */
|
||||
#define X11_I_KEY_PRESS 104 /* 2.1: Pressed key %s */
|
||||
#define X11_I_KEY_RELEASE 105 /* 2.1: Released key %s */
|
||||
#define X11_I_REVISION 107 /* X11 interface revision: %s */
|
||||
#define X11_I_USAGE 108 /* Usage %s: ... */
|
||||
#define X11_I_FACE 109 /* Selected face %s */
|
||||
#define X11_I_NKEYS 110 /* The face has %d keys */
|
||||
#define X11_I_KEY 111 /* Creating key %d, inOut %s */
|
||||
#define X11_I_FOUND_CS 112 /* Found cs widget %s, value %s */
|
||||
#define X11_I_HIER 113 /* Traversing widget %s */
|
||||
#define X11_I_HIER_NC 114 /* Current widget has %d children */
|
||||
#define X11_W_BAD_ACTION_CALL 201 /* Xt Action called with %d args */
|
||||
#define X11_W_UNKNOWN_ATOM 202 /* X Atom %s unknown */
|
||||
#define X11_W_NO_FSB_CONT 203 /* 3.13: FSB continuation not set */
|
||||
#define X11_W_TOO_MANY_MSG 204 /* 3.15: Too many messages (max %d) */
|
||||
#define X11_E_BAD_OPTION 301 /* Invalid option: %s */
|
||||
#define X11_E_NO_WM_COMMAND 302 /* WM_COMMAND property bad/not set */
|
||||
#define X11_E_NO_FSB_TSEG 303 /* 3.13: No txt seg in fsb XmString */
|
||||
#define X11_F_X_ERROR 401 /* X Window System fatal error */
|
||||
#define X11_F_NO_KEYS 402 /* 3.15: Face has no keys */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
void HandleXEvents(void);
|
||||
void IdleXLoop(unsigned long max_wait);
|
||||
void HandleXEvents( void );
|
||||
void IdleXLoop( unsigned long max_wait );
|
||||
|
||||
void InitializeGui(int argc, char *argv[]);
|
||||
void InitializeGui( int argc, char* argv[] );
|
||||
|
||||
void ActivateFSB(char *title, char *file_name, FsbContinuation continuation);
|
||||
void ActivateFSB( char* title, char* file_name, FsbContinuation continuation );
|
||||
|
|
382
src/x_func.c
382
src/x_func.c
|
@ -94,88 +94,71 @@ static char rcs_id[] = "$Id: x_func.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
|||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <X11/Xlib.h> /* Main X header */
|
||||
#include <X11/Intrinsic.h> /* Main Xt header */
|
||||
#include <X11/Xlib.h> /* Main X header */
|
||||
#include <X11/Intrinsic.h> /* Main Xt header */
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
#include "cpu.h"
|
||||
#include "modules.h"
|
||||
#include "disk_io.h"
|
||||
#include "x11.h" /* ActivateFSB() */
|
||||
#include "x11.h" /* ActivateFSB() */
|
||||
#include "x_func.h"
|
||||
#include "args.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID X_FUNC_CHF_MODULE_ID
|
||||
#define CHF_MODULE_ID X_FUNC_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private functions: CPU access
|
||||
Private functions: CPU access
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Return the A field of a DataRegister as an integer. */
|
||||
static int R2int(const Nibble *r)
|
||||
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 ( ( ( 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;
|
||||
}
|
||||
|
||||
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)
|
||||
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 */
|
||||
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<len; c++)
|
||||
{
|
||||
addr += 2;
|
||||
name[c] = (char)toascii(ByteFromAddress(addr));
|
||||
for ( c = 0; c < len; c++ ) {
|
||||
addr += 2;
|
||||
name[ c ] = ( char )toascii( ByteFromAddress( addr ) );
|
||||
}
|
||||
|
||||
name[c] = '\0'; /* Terminate and return the name */
|
||||
name[ c ] = '\0'; /* Terminate and return the name */
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private functions: action routines
|
||||
Private functions: action routines
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Set the emulator speed to the given value (in MHz); the desired speed
|
||||
value is held in the A field of the C CPU register. No handshake.
|
||||
*/
|
||||
static void SetSpeed(Nibble function_code)
|
||||
static void SetSpeed( Nibble function_code )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, X_FUNC_I_CALLED, "SetSpeed");
|
||||
debug1( DEBUG_C_TRACE, X_FUNC_I_CALLED, "SetSpeed" );
|
||||
|
||||
#ifndef REAL_CPU_SPEED
|
||||
ChfCondition X_FUNC_E_NO_SPEED, CHF_ERROR ChfEnd;
|
||||
|
@ -183,149 +166,131 @@ static void SetSpeed(Nibble function_code)
|
|||
|
||||
#else
|
||||
{
|
||||
int new_speed;
|
||||
int new_speed;
|
||||
|
||||
/* Get new_speed from A field of C register */
|
||||
new_speed = R2int(cpu_status.C);
|
||||
/* Get new_speed from A field of C register */
|
||||
new_speed = R2int( cpu_status.C );
|
||||
|
||||
/* Compute inner loop limit; 4 is the real CPU speed in MHz when
|
||||
the limit is set to INNER_LOOP_MAX. No overflow checks,
|
||||
because new_speed is >=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;
|
||||
/* Compute inner loop limit; 4 is the real CPU speed in MHz when
|
||||
the limit is set to INNER_LOOP_MAX. No overflow checks,
|
||||
because new_speed is >=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;
|
||||
/* 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;
|
||||
else
|
||||
ChfCondition X_FUNC_I_MAX_SPEED, CHF_INFO ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
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;
|
||||
struct BinHdrMapping {
|
||||
char* hw;
|
||||
char* hdr;
|
||||
};
|
||||
|
||||
static const struct BinHdrMapping bin_hdr_mapping[] =
|
||||
{
|
||||
{ "hp48", "HPHP48-?" },
|
||||
{ "hp49", "HPHP49-?" }
|
||||
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]))
|
||||
#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)
|
||||
static const char* BinaryHeader( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<N_BIN_HDR_MAPPING; i++)
|
||||
if(strcmp(args.hw, bin_hdr_mapping[i].hw) == 0)
|
||||
return bin_hdr_mapping[i].hdr;
|
||||
for ( i = 0; i < N_BIN_HDR_MAPPING; i++ )
|
||||
if ( strcmp( args.hw, bin_hdr_mapping[ i ].hw ) == 0 )
|
||||
return bin_hdr_mapping[ i ].hdr;
|
||||
|
||||
ChfCondition X_FUNC_E_NO_BIN_HDR, CHF_ERROR, args.hw ChfEnd;
|
||||
return (char *)NULL;
|
||||
return ( char* )NULL;
|
||||
}
|
||||
|
||||
|
||||
/* This function is the continuation of Kget(); it is invoked when the
|
||||
user interaction with the FSB ends.
|
||||
*/
|
||||
static void KgetContinuation(int proceed, char *file_name)
|
||||
static void KgetContinuation( int proceed, char* file_name )
|
||||
{
|
||||
/* Check whether continuation should proceed */
|
||||
if(!proceed)
|
||||
{
|
||||
ChfCondition X_FUNC_W_ABORTED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
if ( !proceed ) {
|
||||
ChfCondition X_FUNC_W_ABORTED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Ok to proceed; read:
|
||||
- target start address from A[A]
|
||||
- target end address from C[A]
|
||||
- binary header with BinaryHeader()
|
||||
*/
|
||||
int start_addr = R2int(cpu_status.A);
|
||||
int end_addr = R2int(cpu_status.C);
|
||||
const char *bin_hdr = BinaryHeader();
|
||||
else {
|
||||
/* Ok to proceed; read:
|
||||
- target start address from A[A]
|
||||
- target end address from C[A]
|
||||
- binary header with BinaryHeader()
|
||||
*/
|
||||
int start_addr = R2int( cpu_status.A );
|
||||
int end_addr = R2int( cpu_status.C );
|
||||
const char* bin_hdr = BinaryHeader();
|
||||
|
||||
debug1(DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name);
|
||||
debug3(DEBUG_C_X_FUNC, X_FUNC_I_KGET, start_addr, end_addr, bin_hdr);
|
||||
debug1( DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name );
|
||||
debug3( DEBUG_C_X_FUNC, X_FUNC_I_KGET, start_addr, end_addr, bin_hdr );
|
||||
|
||||
if(bin_hdr == (const char *)NULL
|
||||
|| ReadObjectFromFile(file_name, bin_hdr, (Address)start_addr,
|
||||
(Address)end_addr))
|
||||
{
|
||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
if ( bin_hdr == ( const char* )NULL || ReadObjectFromFile( file_name, bin_hdr, ( Address )start_addr, ( Address )end_addr ) ) {
|
||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
CpuRunRequest();
|
||||
}
|
||||
|
||||
|
||||
/* This function is the continuation of Send(); it is invoked when the
|
||||
user interaction with the FSB ends.
|
||||
*/
|
||||
static void SendContinuation(int proceed, char *file_name)
|
||||
static void SendContinuation( int proceed, char* file_name )
|
||||
{
|
||||
if(!proceed)
|
||||
{
|
||||
ChfCondition X_FUNC_W_ABORTED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
if ( !proceed ) {
|
||||
ChfCondition X_FUNC_W_ABORTED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Ok to proceed; read:
|
||||
- source start address from A[A]
|
||||
- source end address from C[A]
|
||||
- binary header with BinaryHeader()
|
||||
*/
|
||||
int start_addr = R2int(cpu_status.A);
|
||||
int end_addr = R2int(cpu_status.C);
|
||||
const char *bin_hdr = BinaryHeader();
|
||||
else {
|
||||
/* Ok to proceed; read:
|
||||
- source start address from A[A]
|
||||
- source end address from C[A]
|
||||
- binary header with BinaryHeader()
|
||||
*/
|
||||
int start_addr = R2int( cpu_status.A );
|
||||
int end_addr = R2int( cpu_status.C );
|
||||
const char* bin_hdr = BinaryHeader();
|
||||
|
||||
debug1(DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name);
|
||||
debug3(DEBUG_C_X_FUNC, X_FUNC_I_SEND, start_addr, end_addr, bin_hdr);
|
||||
debug1( DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name );
|
||||
debug3( DEBUG_C_X_FUNC, X_FUNC_I_SEND, start_addr, end_addr, bin_hdr );
|
||||
|
||||
if(bin_hdr == (const char *)NULL
|
||||
|| WriteObjectToFile((Address)start_addr,
|
||||
(Address)end_addr, bin_hdr, file_name))
|
||||
{
|
||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
if ( bin_hdr == ( const char* )NULL || WriteObjectToFile( ( Address )start_addr, ( Address )end_addr, bin_hdr, file_name ) ) {
|
||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
CpuRunRequest();
|
||||
}
|
||||
|
||||
|
||||
/* This function does the setup of a transfer, performing the following
|
||||
actions:
|
||||
|
||||
|
@ -336,137 +301,117 @@ static void SendContinuation(int proceed, char *file_name)
|
|||
be invoked when the user interaction ends
|
||||
- Halts the CPU
|
||||
*/
|
||||
static void SetupXfer(
|
||||
int msg, const char *def_msg, FsbContinuation cont)
|
||||
static void SetupXfer( int msg, const char* def_msg, FsbContinuation cont )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, X_FUNC_I_CALLED, "SetupXfer");
|
||||
debug1( DEBUG_C_TRACE, X_FUNC_I_CALLED, "SetupXfer" );
|
||||
|
||||
if(CpuHaltAllowed())
|
||||
{
|
||||
char *fsb_title =
|
||||
XtNewString(ChfGetMessage(CHF_MODULE_ID, msg, def_msg));
|
||||
if ( CpuHaltAllowed() ) {
|
||||
char* fsb_title = XtNewString( ChfGetMessage( CHF_MODULE_ID, msg, def_msg ) );
|
||||
|
||||
char *fsb_file =
|
||||
NameFromD1();
|
||||
char* fsb_file = NameFromD1();
|
||||
|
||||
ActivateFSB(fsb_title, fsb_file, cont);
|
||||
ActivateFSB( fsb_title, fsb_file, cont );
|
||||
|
||||
/* Free *before* CpuHaltRequest() because it does not return, and
|
||||
ActivateFSB() copied its argument when necessary.
|
||||
*/
|
||||
XtFree(fsb_title);
|
||||
XtFree(fsb_file);
|
||||
/* Free *before* CpuHaltRequest() because it does not return, and
|
||||
ActivateFSB() copied its argument when necessary.
|
||||
*/
|
||||
XtFree( fsb_title );
|
||||
XtFree( fsb_file );
|
||||
|
||||
(void)CpuHaltRequest();
|
||||
( void )CpuHaltRequest();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
ChfCondition X_FUNC_E_NO_HALT, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
else {
|
||||
ChfCondition X_FUNC_E_NO_HALT, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This is the emulator's extended function for 'kget': this function
|
||||
transfers a file from disk into the calculator's memory.
|
||||
*/
|
||||
static void Kget(Nibble function_code)
|
||||
static void Kget( Nibble function_code )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, X_FUNC_I_CALLED, "Kget");
|
||||
debug1( DEBUG_C_TRACE, X_FUNC_I_CALLED, "Kget" );
|
||||
|
||||
/* Setup File Selection Box if transfers are *not* in batch mode */
|
||||
if(! args.batchXfer)
|
||||
SetupXfer(X_FUNC_M_KGET, "Kget", KgetContinuation);
|
||||
if ( !args.batchXfer )
|
||||
SetupXfer( X_FUNC_M_KGET, "Kget", KgetContinuation );
|
||||
|
||||
else
|
||||
{
|
||||
/* Ok to proceed; read:
|
||||
- file name from @D1
|
||||
- target start address from A[A]
|
||||
- target end address from C[A]
|
||||
- binary header with BinaryHeader()
|
||||
*/
|
||||
char *file_name = NameFromD1();
|
||||
int start_addr = R2int(cpu_status.A);
|
||||
int end_addr = R2int(cpu_status.C);
|
||||
const char *bin_hdr = BinaryHeader();
|
||||
else {
|
||||
/* Ok to proceed; read:
|
||||
- file name from @D1
|
||||
- target start address from A[A]
|
||||
- target end address from C[A]
|
||||
- binary header with BinaryHeader()
|
||||
*/
|
||||
char* file_name = NameFromD1();
|
||||
int start_addr = R2int( cpu_status.A );
|
||||
int end_addr = R2int( cpu_status.C );
|
||||
const char* bin_hdr = BinaryHeader();
|
||||
|
||||
debug1(DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name);
|
||||
debug3(DEBUG_C_X_FUNC, X_FUNC_I_KGET, start_addr, end_addr, bin_hdr);
|
||||
debug1( DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name );
|
||||
debug3( DEBUG_C_X_FUNC, X_FUNC_I_KGET, start_addr, end_addr, bin_hdr );
|
||||
|
||||
if(bin_hdr == (const char *)NULL
|
||||
|| ReadObjectFromFile(file_name, bin_hdr, (Address)start_addr,
|
||||
(Address)end_addr))
|
||||
{
|
||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
if ( bin_hdr == ( const char* )NULL || ReadObjectFromFile( file_name, bin_hdr, ( Address )start_addr, ( Address )end_addr ) ) {
|
||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This is the emulator's extended function for 'send': this function
|
||||
transfers an object from the calculator's memory into a disk file.
|
||||
*/
|
||||
static void Send(Nibble function_code)
|
||||
static void Send( Nibble function_code )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, X_FUNC_I_CALLED, "Send");
|
||||
debug1( DEBUG_C_TRACE, X_FUNC_I_CALLED, "Send" );
|
||||
|
||||
/* Setup File Selection Box if transfers are *not* in batch mode */
|
||||
if(! args.batchXfer)
|
||||
SetupXfer(X_FUNC_M_SEND, "Send", SendContinuation);
|
||||
if ( !args.batchXfer )
|
||||
SetupXfer( X_FUNC_M_SEND, "Send", SendContinuation );
|
||||
|
||||
else
|
||||
{
|
||||
/* Ok to proceed; read:
|
||||
- file name from @D1
|
||||
- source start address from A[A]
|
||||
- source end address from C[A]
|
||||
- binary header with BinaryHeader()
|
||||
*/
|
||||
char *file_name = NameFromD1();
|
||||
int start_addr = R2int(cpu_status.A);
|
||||
int end_addr = R2int(cpu_status.C);
|
||||
const char *bin_hdr = BinaryHeader();
|
||||
else {
|
||||
/* Ok to proceed; read:
|
||||
- file name from @D1
|
||||
- source start address from A[A]
|
||||
- source end address from C[A]
|
||||
- binary header with BinaryHeader()
|
||||
*/
|
||||
char* file_name = NameFromD1();
|
||||
int start_addr = R2int( cpu_status.A );
|
||||
int end_addr = R2int( cpu_status.C );
|
||||
const char* bin_hdr = BinaryHeader();
|
||||
|
||||
debug1(DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name);
|
||||
debug3(DEBUG_C_X_FUNC, X_FUNC_I_SEND, start_addr, end_addr, bin_hdr);
|
||||
debug1( DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name );
|
||||
debug3( DEBUG_C_X_FUNC, X_FUNC_I_SEND, start_addr, end_addr, bin_hdr );
|
||||
|
||||
if(bin_hdr == (const char *)NULL
|
||||
|| WriteObjectToFile((Address)start_addr,
|
||||
(Address)end_addr, bin_hdr, file_name))
|
||||
{
|
||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
if ( bin_hdr == ( const char* )NULL || WriteObjectToFile( ( Address )start_addr, ( Address )end_addr, bin_hdr, file_name ) ) {
|
||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Dispatch table of emulator's extended functions, indexed by function code;
|
||||
the function code is propagated to functions in the table.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
typedef void (*XFunc)(Nibble);
|
||||
typedef void ( *XFunc )( Nibble );
|
||||
|
||||
static const XFunc function[] =
|
||||
{
|
||||
SetSpeed, /* Function code 0 */
|
||||
Kget, /* 1 */
|
||||
Send /* 2 */
|
||||
static const XFunc function[] = {
|
||||
SetSpeed, /* Function code 0 */
|
||||
Kget, /* 1 */
|
||||
Send /* 2 */
|
||||
};
|
||||
|
||||
#define N_X_FUNC (sizeof(function)/sizeof(function[0]))
|
||||
|
||||
|
||||
#define N_X_FUNC ( sizeof( function ) / sizeof( function[ 0 ] ) )
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
@ -480,35 +425,32 @@ static const XFunc function[] =
|
|||
the calculator side are made through CPU registers.
|
||||
|
||||
.call :
|
||||
ExtendedFunction(function_code);
|
||||
ExtendedFunction(function_code);
|
||||
.input :
|
||||
Nibble function_code, function code
|
||||
Nibble function_code, function code
|
||||
.output :
|
||||
void
|
||||
void
|
||||
.status_codes :
|
||||
X_FUNC_I_CALLED
|
||||
X_FUNC_I_CODE
|
||||
X_FUNC_W_BAD_CODE
|
||||
* Any other condition code generated by action functions
|
||||
X_FUNC_I_CALLED
|
||||
X_FUNC_I_CODE
|
||||
X_FUNC_W_BAD_CODE
|
||||
* Any other condition code generated by action functions
|
||||
.notes :
|
||||
3.13, 3-Nov-2000, creation
|
||||
|
||||
.- */
|
||||
void ExtendedFunction(Nibble function_code)
|
||||
void ExtendedFunction( Nibble function_code )
|
||||
{
|
||||
debug1(DEBUG_C_TRACE, X_FUNC_I_CALLED, "ExtendedFunction");
|
||||
debug1(DEBUG_C_X_FUNC, X_FUNC_I_CODE, function_code);
|
||||
debug1( DEBUG_C_TRACE, X_FUNC_I_CALLED, "ExtendedFunction" );
|
||||
debug1( DEBUG_C_X_FUNC, X_FUNC_I_CODE, function_code );
|
||||
|
||||
/* Some sanity checks, first */
|
||||
if(function_code < 0
|
||||
|| function_code >= N_X_FUNC
|
||||
|| function[(int)function_code] == (XFunc)NULL)
|
||||
{
|
||||
ChfCondition X_FUNC_W_BAD_CODE, CHF_WARNING, function_code ChfEnd;
|
||||
ChfSignal();
|
||||
if ( function_code < 0 || function_code >= 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);
|
||||
function[ ( int )function_code ]( function_code );
|
||||
}
|
||||
|
|
49
src/x_func.h
49
src/x_func.h
|
@ -69,41 +69,38 @@
|
|||
|
||||
.- */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macro/Data type definitions - require cpu.h
|
||||
Macro/Data type definitions - require cpu.h
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Extended function codes (argument of XFunction()) */
|
||||
#define X_FUNC_SET_SPEED (Nibble)0
|
||||
#define X_FUNC_KGET (Nibble)1
|
||||
#define X_FUNC_SEND (Nibble)2
|
||||
|
||||
#define X_FUNC_SET_SPEED ( Nibble )0
|
||||
#define X_FUNC_KGET ( Nibble )1
|
||||
#define X_FUNC_SEND ( Nibble )2
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf condition codes
|
||||
Chf condition codes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define X_FUNC_I_CALLED 101 /* Function %s called */
|
||||
#define X_FUNC_I_CODE 102 /* Function code %d */
|
||||
#define X_FUNC_I_SET_SPEED 103 /* Speed set to %dMhz (%d mult.) */
|
||||
#define X_FUNC_I_MAX_SPEED 104 /* Emulator at max speed */
|
||||
#define X_FUNC_I_FILE_NAME 105 /* Transferring file name %s */
|
||||
#define X_FUNC_I_KGET 106 /* Kget start:%x end:%x hdr:%s */
|
||||
#define X_FUNC_I_SEND 107 /* Send start:%x end:%x hdr:%s */
|
||||
#define X_FUNC_W_BAD_CODE 201 /* Bad function code %d ignored */
|
||||
#define X_FUNC_W_ABORTED 202 /* Aborted by user */
|
||||
#define X_FUNC_W_FAILED 203 /* Operation failed */
|
||||
#define X_FUNC_E_NO_HALT 301 /* Cpu halt not allowed */
|
||||
#define X_FUNC_E_NO_SPEED 302 /* No speed control available */
|
||||
#define X_FUNC_E_NO_BIN_HDR 303 /* Can't determine hdr for hw %s */
|
||||
#define X_FUNC_F_xxx 401
|
||||
#define X_FUNC_M_KGET 501 /* FSB title for Kget function */
|
||||
#define X_FUNC_M_SEND 502 /* FSB title for Send function */
|
||||
|
||||
#define X_FUNC_I_CALLED 101 /* Function %s called */
|
||||
#define X_FUNC_I_CODE 102 /* Function code %d */
|
||||
#define X_FUNC_I_SET_SPEED 103 /* Speed set to %dMhz (%d mult.) */
|
||||
#define X_FUNC_I_MAX_SPEED 104 /* Emulator at max speed */
|
||||
#define X_FUNC_I_FILE_NAME 105 /* Transferring file name %s */
|
||||
#define X_FUNC_I_KGET 106 /* Kget start:%x end:%x hdr:%s */
|
||||
#define X_FUNC_I_SEND 107 /* Send start:%x end:%x hdr:%s */
|
||||
#define X_FUNC_W_BAD_CODE 201 /* Bad function code %d ignored */
|
||||
#define X_FUNC_W_ABORTED 202 /* Aborted by user */
|
||||
#define X_FUNC_W_FAILED 203 /* Operation failed */
|
||||
#define X_FUNC_E_NO_HALT 301 /* Cpu halt not allowed */
|
||||
#define X_FUNC_E_NO_SPEED 302 /* No speed control available */
|
||||
#define X_FUNC_E_NO_BIN_HDR 303 /* Can't determine hdr for hw %s */
|
||||
#define X_FUNC_F_xxx 401
|
||||
#define X_FUNC_M_KGET 501 /* FSB title for Kget function */
|
||||
#define X_FUNC_M_SEND 502 /* FSB title for Send function */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
void ExtendedFunction(Nibble function_code);
|
||||
void ExtendedFunction( Nibble function_code );
|
||||
|
|
Loading…
Reference in a new issue