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
|
# Formatting
|
||||||
pretty-code:
|
pretty-code:
|
||||||
clang-format -i src/*.c src/*.h
|
clang-format -i src/*.c src/*.h src/libChf/*.c src/libChf/*.h
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
get-roms:
|
get-roms:
|
||||||
|
|
30
src/args.h
30
src/args.h
|
@ -74,27 +74,25 @@
|
||||||
.- */
|
.- */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Data type definitions - require config.h
|
Data type definitions - require config.h
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
struct Args
|
struct Args {
|
||||||
{
|
int reset; /* 2.1: Force emulator reset */
|
||||||
int reset; /* 2.1: Force emulator reset */
|
int monitor; /* 2.1: Call monitor() on startup */
|
||||||
int monitor; /* 2.1: Call monitor() on startup */
|
int batchXfer; /* 3.15: Non-interactive file transfers */
|
||||||
int batchXfer; /* 3.15: Non-interactive file transfers */
|
char* mod_file_name;
|
||||||
char *mod_file_name;
|
char* cpu_file_name;
|
||||||
char *cpu_file_name;
|
char* hdw_file_name;
|
||||||
char *hdw_file_name;
|
char* rom_file_name;
|
||||||
char *rom_file_name;
|
char* ram_file_name;
|
||||||
char *ram_file_name;
|
char* port_1_file_name;
|
||||||
char *port_1_file_name;
|
char* port_2_file_name;
|
||||||
char *port_2_file_name;
|
char* hw; /* 2.1: Hardware configuration (unused) */
|
||||||
char *hw; /* 2.1: Hardware configuration (unused) */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Global variables
|
Global variables
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
extern struct Args args;
|
extern struct Args args;
|
||||||
|
|
44
src/config.h
44
src/config.h
|
@ -121,14 +121,12 @@
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
|
|
||||||
|
|
||||||
/* CHF_EXTENDED_INFO:
|
/* CHF_EXTENDED_INFO:
|
||||||
Define this symbol if extended information is desired during condition
|
Define this symbol if extended information is desired during condition
|
||||||
handling; this is usually useful only for debugging purposes.
|
handling; this is usually useful only for debugging purposes.
|
||||||
*/
|
*/
|
||||||
/* #define CHF_EXTENDED_INFO */
|
/* #define CHF_EXTENDED_INFO */
|
||||||
|
|
||||||
|
|
||||||
/* DEBUG:
|
/* DEBUG:
|
||||||
Define this symbol to include the debugging code for all source modules
|
Define this symbol to include the debugging code for all source modules
|
||||||
in the executable image.
|
in the executable image.
|
||||||
|
@ -139,7 +137,6 @@
|
||||||
*/
|
*/
|
||||||
/* #define DEBUG */
|
/* #define DEBUG */
|
||||||
|
|
||||||
|
|
||||||
/* DEBUG_LEVEL:
|
/* 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
|
in the executable image (DEBUG symbol set), the initial debug level
|
||||||
|
@ -149,8 +146,7 @@
|
||||||
DEBUG_C_<> defined in debug.h; each of them corresponds to a class
|
DEBUG_C_<> defined in debug.h; each of them corresponds to a class
|
||||||
of debugging conditions that can be individually enabled or disabled.
|
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
|
/* CPU_SPIN_SHUTDN
|
||||||
If this symbol is defined, the cpu module implements the SHUTDN
|
If this symbol is defined, the cpu module implements the SHUTDN
|
||||||
|
@ -176,7 +172,6 @@
|
||||||
*/
|
*/
|
||||||
/* #define CPU_SPIN_SHUTDN */
|
/* #define CPU_SPIN_SHUTDN */
|
||||||
|
|
||||||
|
|
||||||
/* 2.1: FORCE_NONMODAL
|
/* 2.1: FORCE_NONMODAL
|
||||||
If this symbol is defined, nonmodal navigation is forced in the
|
If this symbol is defined, nonmodal navigation is forced in the
|
||||||
OSF/Motif GUI, by setting navigationType to XmNONE and traversalOn
|
OSF/Motif GUI, by setting navigationType to XmNONE and traversalOn
|
||||||
|
@ -184,15 +179,13 @@
|
||||||
*/
|
*/
|
||||||
/* #define FORCE_NONMODAL */
|
/* #define FORCE_NONMODAL */
|
||||||
|
|
||||||
|
|
||||||
/* 2.4: N_PORT_2_BANK
|
/* 2.4: N_PORT_2_BANK
|
||||||
This symbol is used to dimension the HP48GX Port_2: it denotes the
|
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
|
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.
|
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.
|
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
|
/* 2.5: SERIAL_FORCE_OPENPTY, SERIAL_FORCE_STREAMSPTY
|
||||||
Optionally define exactly one of these symbols to force the use of a
|
Optionally define exactly one of these symbols to force the use of a
|
||||||
|
@ -203,7 +196,6 @@
|
||||||
/* #define SERIAL_FORCE_OPENPTY */
|
/* #define SERIAL_FORCE_OPENPTY */
|
||||||
/* #define SERIAL_FORCE_STREAMSPTY */
|
/* #define SERIAL_FORCE_STREAMSPTY */
|
||||||
|
|
||||||
|
|
||||||
/* 3.2: HP49_SUPPORT
|
/* 3.2: HP49_SUPPORT
|
||||||
Define this symbol to enable HP49-specific support code in the
|
Define this symbol to enable HP49-specific support code in the
|
||||||
emulator; it does not harm if this symbol is defined when emulating
|
emulator; it does not harm if this symbol is defined when emulating
|
||||||
|
@ -211,7 +203,6 @@
|
||||||
*/
|
*/
|
||||||
#define HP49_SUPPORT
|
#define HP49_SUPPORT
|
||||||
|
|
||||||
|
|
||||||
/* 3.13: REAL_CPU_SPEED
|
/* 3.13: REAL_CPU_SPEED
|
||||||
Define this symbol (recommended) to force the emulated CPU to run
|
Define this symbol (recommended) to force the emulated CPU to run
|
||||||
no faster than a software-controlled limit; by default, the limit
|
no faster than a software-controlled limit; by default, the limit
|
||||||
|
@ -219,7 +210,6 @@
|
||||||
*/
|
*/
|
||||||
#define REAL_CPU_SPEED
|
#define REAL_CPU_SPEED
|
||||||
|
|
||||||
|
|
||||||
/* 3.14: CPU_SLOW_IN
|
/* 3.14: CPU_SLOW_IN
|
||||||
Define this symbol (recommended) to slow down the A=IN and C=IN
|
Define this symbol (recommended) to slow down the A=IN and C=IN
|
||||||
instructions depending on the current emulated CPU speed.
|
instructions depending on the current emulated CPU speed.
|
||||||
|
@ -227,8 +217,7 @@
|
||||||
The value of the macro determines the gain of the relation between
|
The value of the macro determines the gain of the relation between
|
||||||
CPU speed and slow down ratio.
|
CPU speed and slow down ratio.
|
||||||
*/
|
*/
|
||||||
#define CPU_SLOW_IN 16
|
#define CPU_SLOW_IN 16
|
||||||
|
|
||||||
|
|
||||||
/* 4.1.1.1: LCD_MAG
|
/* 4.1.1.1: LCD_MAG
|
||||||
This symbol represents the magnification ratio of the emulated LCD pixels
|
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
|
default. Currently, the value cannot be set at runtime for performance
|
||||||
reasons.
|
reasons.
|
||||||
*/
|
*/
|
||||||
#define LCD_MAG 2
|
#define LCD_MAG 2
|
||||||
|
|
||||||
|
|
||||||
/* 4.1.1.1: When defined, this symbol represents the threshold of the long
|
/* 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
|
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
|
for more than LONG_PRESS_THR milliseconds, the key stays pressed after
|
||||||
release.
|
release.
|
||||||
*/
|
*/
|
||||||
#define LONG_PRESS_THR 1000
|
#define LONG_PRESS_THR 1000
|
||||||
|
|
||||||
|
|
||||||
/* Chf Module Identifiers:
|
/* Chf Module Identifiers:
|
||||||
Each main module of the emulator has its own Chf Module Identifier; the
|
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.
|
values defined here must match those actually used in the message catalogs.
|
||||||
*/
|
*/
|
||||||
#define MAIN_CHF_MODULE_ID 10
|
#define MAIN_CHF_MODULE_ID 10
|
||||||
#define CPU_CHF_MODULE_ID 11
|
#define CPU_CHF_MODULE_ID 11
|
||||||
#define MOD_CHF_MODULE_ID 12
|
#define MOD_CHF_MODULE_ID 12
|
||||||
#define DISK_IO_CHF_MODULE_ID 13
|
#define DISK_IO_CHF_MODULE_ID 13
|
||||||
#define X11_CHF_MODULE_ID 14
|
#define X11_CHF_MODULE_ID 14
|
||||||
#define SERIAL_CHF_MODULE_ID 15 /* 2.5 */
|
#define SERIAL_CHF_MODULE_ID 15 /* 2.5 */
|
||||||
#define FLASH_CHF_MODULE_ID 16 /* 3.3 */
|
#define FLASH_CHF_MODULE_ID 16 /* 3.3 */
|
||||||
#define UTIL_CHF_MODULE_ID 17 /* 3.6 */
|
#define UTIL_CHF_MODULE_ID 17 /* 3.6 */
|
||||||
#define X_FUNC_CHF_MODULE_ID 18 /* 3.13 */
|
#define X_FUNC_CHF_MODULE_ID 18 /* 3.13 */
|
||||||
#define DEBUG_CHF_MODULE_ID 30
|
#define DEBUG_CHF_MODULE_ID 30
|
||||||
|
|
||||||
|
|
||||||
/* 3.16: Include automatic exceptions to user configuration */
|
/* 3.16: Include automatic exceptions to user configuration */
|
||||||
#include "config_x.h"
|
#include "config_x.h"
|
||||||
|
|
|
@ -58,8 +58,7 @@
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
|
|
||||||
|
|
||||||
/* REAL_CPU_SPEED is not supported on ultrix, because there is no usleep() */
|
/* REAL_CPU_SPEED is not supported on ultrix, because there is no usleep() */
|
||||||
#ifdef ultrix
|
#ifdef ultrix
|
||||||
#undef REAL_CPU_SPEED
|
# undef REAL_CPU_SPEED
|
||||||
#endif
|
#endif
|
||||||
|
|
333
src/cpu.h
333
src/cpu.h
|
@ -67,8 +67,8 @@
|
||||||
requests and emulator's extended functions:
|
requests and emulator's extended functions:
|
||||||
|
|
||||||
- Added new fields:
|
- Added new fields:
|
||||||
struct CpuStatus.halt (number of pending halt requests)
|
struct CpuStatus.halt (number of pending halt requests)
|
||||||
struct CpuStatus.inner_loop_max (upper limit of inner_loop)
|
struct CpuStatus.inner_loop_max (upper limit of inner_loop)
|
||||||
- New condition codes: CPU_I_HALT, CPU_I_RUN, CPU_E_NO_HALT
|
- New condition codes: CPU_I_HALT, CPU_I_RUN, CPU_E_NO_HALT
|
||||||
- New prototypes: CpuHaltRequest(), CpuRunRequest(), CpuHaltAllowed()
|
- 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
|
N_SCRATCH_REGISTER_ALL, used during scratch register space allocation
|
||||||
is larger than necessary to avoid additional checks on the validity of
|
is larger than necessary to avoid additional checks on the validity of
|
||||||
|
@ -115,238 +114,224 @@
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* General */
|
/* General */
|
||||||
#define NIBBLE_PER_REGISTER 16
|
#define NIBBLE_PER_REGISTER 16
|
||||||
#define N_WORKING_REGISTER 4
|
#define N_WORKING_REGISTER 4
|
||||||
#define N_SCRATCH_REGISTER 5
|
#define N_SCRATCH_REGISTER 5
|
||||||
#define N_SCRATCH_REGISTER_ALL 8
|
#define N_SCRATCH_REGISTER_ALL 8
|
||||||
#define N_DATA_POINTER_REGISTER 2
|
#define N_DATA_POINTER_REGISTER 2
|
||||||
#define RETURN_STACK_SIZE 8
|
#define RETURN_STACK_SIZE 8
|
||||||
#define NIBBLE_VALUES 16
|
#define NIBBLE_VALUES 16
|
||||||
|
|
||||||
#define INT_HANDLER_PC ((Address)0x0000F)
|
#define INT_HANDLER_PC ( ( Address )0x0000F )
|
||||||
|
|
||||||
#define DISASSEMBLE_OB_SIZE 128
|
#define DISASSEMBLE_OB_SIZE 128
|
||||||
#define DUMP_CPU_STATUS_OB_SIZE 512
|
#define DUMP_CPU_STATUS_OB_SIZE 512
|
||||||
|
|
||||||
#define CPU_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
|
||||||
|
|
||||||
|
#define CPU_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||||
|
|
||||||
/* Instruction opcode access macros:
|
/* Instruction opcode access macros:
|
||||||
GetFS(f) returns the short field-selector value from the
|
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
|
GetImmFS(f) returns the immediate-field-selector flag from the
|
||||||
given nibble (bit 3)
|
given nibble (bit 3)
|
||||||
=0: regular field selector
|
=0: regular field selector
|
||||||
!=0: immediate field selector
|
!=0: immediate field selector
|
||||||
|
|
||||||
GetOC_1(o) returns the short operation code from the given
|
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
|
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
|
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
|
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
|
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
|
GetAC(r) returns the A/C register flag from the given nibble
|
||||||
(bit 3)
|
(bit 3)
|
||||||
=0: register A
|
=0: register A
|
||||||
!=0: register C
|
!=0: register C
|
||||||
|
|
||||||
GetAS(r) returns the add/subtract flag from the given nibble
|
GetAS(r) returns the add/subtract flag from the given nibble
|
||||||
(bit 3)
|
(bit 3)
|
||||||
=0: add
|
=0: add
|
||||||
!=0: subtract
|
!=0: subtract
|
||||||
*/
|
*/
|
||||||
#define GetFS(f) ((f) & 0x7)
|
#define GetFS( f ) ( ( f ) & 0x7 )
|
||||||
#define GetImmFS(o) ((o) & 0x8)
|
#define GetImmFS( o ) ( ( o ) & 0x8 )
|
||||||
#define GetOC_1(o) (((o) & 0xC)>>2)
|
#define GetOC_1( o ) ( ( ( o ) & 0xC ) >> 2 )
|
||||||
#define GetOC_2(f, o) ((((f) & 0x8)>>1) | (((o) & 0xC)>>2))
|
#define GetOC_2( f, o ) ( ( ( ( f ) & 0x8 ) >> 1 ) | ( ( ( o ) & 0xC ) >> 2 ) )
|
||||||
#define GetOC_3b(o) ((o) & 0x7)
|
#define GetOC_3b( o ) ( ( o ) & 0x7 )
|
||||||
#define GetRP(o) ((o) & 0x3)
|
#define GetRP( o ) ( ( o ) & 0x3 )
|
||||||
#define GetRn(r) ((r) & 0x7)
|
#define GetRn( r ) ( ( r ) & 0x7 )
|
||||||
#define GetAC(r) ((r) & 0x8)
|
#define GetAC( r ) ( ( r ) & 0x8 )
|
||||||
#define GetAS(r) ((r) & 0x8)
|
#define GetAS( r ) ( ( r ) & 0x8 )
|
||||||
|
|
||||||
|
|
||||||
/* Field selector codes */
|
/* Field selector codes */
|
||||||
#define FS_P 0
|
#define FS_P 0
|
||||||
#define FS_WP 1
|
#define FS_WP 1
|
||||||
#define FS_XS 2
|
#define FS_XS 2
|
||||||
#define FS_X 3
|
#define FS_X 3
|
||||||
#define FS_S 4
|
#define FS_S 4
|
||||||
#define FS_M 5
|
#define FS_M 5
|
||||||
#define FS_B 6
|
#define FS_B 6
|
||||||
#define FS_W 7
|
#define FS_W 7
|
||||||
#define FS_A 15
|
#define FS_A 15
|
||||||
#define N_FS 16 /* Total # of FS codes */
|
#define N_FS 16 /* Total # of FS codes */
|
||||||
|
|
||||||
|
|
||||||
/* Register pair codes */
|
/* Register pair codes */
|
||||||
#define RP_AB 0
|
#define RP_AB 0
|
||||||
#define RP_BC 1
|
#define RP_BC 1
|
||||||
#define RP_CA 2
|
#define RP_CA 2
|
||||||
#define RP_DC 3
|
#define RP_DC 3
|
||||||
#define N_RP 4 /* Total # of RP codes */
|
#define N_RP 4 /* Total # of RP codes */
|
||||||
|
|
||||||
|
|
||||||
/* Masks */
|
/* Masks */
|
||||||
#define NIBBLE_MASK ((Nibble)0xF)
|
#define NIBBLE_MASK ( ( Nibble )0xF )
|
||||||
#define ADDRESS_MASK ((Address)0xFFFFF)
|
#define ADDRESS_MASK ( ( Address )0xFFFFF )
|
||||||
|
|
||||||
#define CLRST_MASK ((ProgramStatusRegister)0xF000)
|
#define CLRST_MASK ( ( ProgramStatusRegister )0xF000 )
|
||||||
#define D_S_MASK ((Address)0xF0000)
|
#define D_S_MASK ( ( Address )0xF0000 )
|
||||||
#define RETURN_SP_MASK 0x7
|
#define RETURN_SP_MASK 0x7
|
||||||
|
|
||||||
|
typedef int1 Bit;
|
||||||
typedef int1 Bit;
|
typedef int4 Nibble;
|
||||||
typedef int4 Nibble;
|
typedef int20 Address;
|
||||||
typedef int20 Address;
|
typedef int12 OutputRegister;
|
||||||
typedef int12 OutputRegister;
|
typedef int16 InputRegister;
|
||||||
typedef int16 InputRegister;
|
typedef int16 ProgramStatusRegister;
|
||||||
typedef int16 ProgramStatusRegister;
|
typedef Nibble DataRegister[ NIBBLE_PER_REGISTER ];
|
||||||
typedef Nibble DataRegister[NIBBLE_PER_REGISTER];
|
|
||||||
|
|
||||||
/* The XAddress data type holds extended addresses used to access Port 2 */
|
/* The XAddress data type holds extended addresses used to access Port 2 */
|
||||||
typedef int32 XAddress;
|
typedef int32 XAddress;
|
||||||
|
|
||||||
enum IntRequest
|
enum IntRequest { INT_REQUEST_NONE, INT_REQUEST_IRQ, INT_REQUEST_NMI };
|
||||||
{
|
|
||||||
INT_REQUEST_NONE,
|
|
||||||
INT_REQUEST_IRQ,
|
|
||||||
INT_REQUEST_NMI
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CpuStatus
|
struct CpuStatus {
|
||||||
{
|
DataRegister work[ N_WORKING_REGISTER ];
|
||||||
DataRegister work[N_WORKING_REGISTER];
|
#define A work[ 0 ]
|
||||||
#define A work[0]
|
#define B work[ 1 ]
|
||||||
#define B work[1]
|
#define C work[ 2 ]
|
||||||
#define C work[2]
|
#define D work[ 3 ]
|
||||||
#define D work[3]
|
|
||||||
|
|
||||||
DataRegister R[N_SCRATCH_REGISTER_ALL];
|
DataRegister R[ N_SCRATCH_REGISTER_ALL ];
|
||||||
#define R0 R[0]
|
#define R0 R[ 0 ]
|
||||||
#define R1 R[1]
|
#define R1 R[ 1 ]
|
||||||
#define R2 R[2]
|
#define R2 R[ 2 ]
|
||||||
#define R3 R[3]
|
#define R3 R[ 3 ]
|
||||||
#define R4 R[4]
|
#define R4 R[ 4 ]
|
||||||
|
|
||||||
Address DAT[N_DATA_POINTER_REGISTER];
|
Address DAT[ N_DATA_POINTER_REGISTER ];
|
||||||
#define D0 DAT[0]
|
#define D0 DAT[ 0 ]
|
||||||
#define D1 DAT[1]
|
#define D1 DAT[ 1 ]
|
||||||
|
|
||||||
Nibble P;
|
Nibble P;
|
||||||
Address PC;
|
Address PC;
|
||||||
InputRegister IN;
|
InputRegister IN;
|
||||||
OutputRegister OUT;
|
OutputRegister OUT;
|
||||||
ProgramStatusRegister ST;
|
ProgramStatusRegister ST;
|
||||||
|
|
||||||
Nibble HST;
|
Nibble HST;
|
||||||
#define HST_MP_MASK 0x08
|
#define HST_MP_MASK 0x08
|
||||||
#define HST_SR_MASK 0x04
|
#define HST_SR_MASK 0x04
|
||||||
#define HST_SB_MASK 0x02
|
#define HST_SB_MASK 0x02
|
||||||
#define HST_XM_MASK 0x01
|
#define HST_XM_MASK 0x01
|
||||||
|
|
||||||
Address return_stack[RETURN_STACK_SIZE];
|
Address return_stack[ RETURN_STACK_SIZE ];
|
||||||
int return_sp;
|
int return_sp;
|
||||||
|
|
||||||
int fs_idx_lo[N_FS];
|
int fs_idx_lo[ N_FS ];
|
||||||
int fs_idx_hi[N_FS];
|
int fs_idx_hi[ N_FS ];
|
||||||
int hexmode; /* DEC/HEX mode, 1=HEX */
|
int hexmode; /* DEC/HEX mode, 1=HEX */
|
||||||
int carry; /* Carry bit 1=set */
|
int carry; /* Carry bit 1=set */
|
||||||
int shutdn; /* SHUTDN flag, 1=executed */
|
int shutdn; /* SHUTDN flag, 1=executed */
|
||||||
int halt; /* 3.13: # of pending Halt */
|
int halt; /* 3.13: # of pending Halt */
|
||||||
int int_enable; /* Int. enable, 1=enabled */
|
int int_enable; /* Int. enable, 1=enabled */
|
||||||
int int_service; /* Int. service, 1=service */
|
int int_service; /* Int. service, 1=service */
|
||||||
enum IntRequest int_pending; /* Pending interrupt request */
|
enum IntRequest int_pending; /* Pending interrupt request */
|
||||||
|
|
||||||
/* 3.13: inner_loop_max gives the upper limit of the CPU speed if the
|
/* 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
|
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
|
it has the default value INNER_LOOP_MAX, that should be close to the
|
||||||
real cpu speed (~4MHz).
|
real cpu speed (~4MHz).
|
||||||
*/
|
*/
|
||||||
int inner_loop; /* Inner loop multiplier */
|
int inner_loop; /* Inner loop multiplier */
|
||||||
int inner_loop_max; /* Max value of inner_loop */
|
int inner_loop_max; /* Max value of inner_loop */
|
||||||
#define INNER_LOOP_MAX 26
|
#define INNER_LOOP_MAX 26
|
||||||
#define INNER_LOOP_MED 13
|
#define INNER_LOOP_MED 13
|
||||||
#define INNER_LOOP_MIN 2
|
#define INNER_LOOP_MIN 2
|
||||||
|
|
||||||
#ifdef CPU_SPIN_LOOP
|
#ifdef CPU_SPIN_LOOP
|
||||||
int reset_req; /* Reset req. after shutdn */
|
int reset_req; /* Reset req. after shutdn */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ExitOption /* 2.1: EmulatorExit() option */
|
enum ExitOption /* 2.1: EmulatorExit() option */
|
||||||
{
|
{
|
||||||
IMMEDIATE_EXIT,
|
IMMEDIATE_EXIT,
|
||||||
SAVE_AND_EXIT
|
SAVE_AND_EXIT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Global variables
|
Global variables
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
extern struct CpuStatus cpu_status;
|
extern struct CpuStatus cpu_status;
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Chf condition codes
|
Chf condition codes
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define CPU_I_CALLED 101 /* Function %s called */
|
#define CPU_I_CALLED 101 /* Function %s called */
|
||||||
#define CPU_I_EXECUTING 102 /* Executing @PC %X */
|
#define CPU_I_EXECUTING 102 /* Executing @PC %X */
|
||||||
#define CPU_I_SHUTDN 103 /* Shutdown */
|
#define CPU_I_SHUTDN 103 /* Shutdown */
|
||||||
#define CPU_I_WAKE 104 /* Wake */
|
#define CPU_I_WAKE 104 /* Wake */
|
||||||
#define CPU_I_INT 105 /* %s request accepted */
|
#define CPU_I_INT 105 /* %s request accepted */
|
||||||
#define CPU_I_INT_PENDING 106 /* %s request pending */
|
#define CPU_I_INT_PENDING 106 /* %s request pending */
|
||||||
#define CPU_I_RTI_LOOP 107 /* RTI loop to service %s */
|
#define CPU_I_RTI_LOOP 107 /* RTI loop to service %s */
|
||||||
#define CPU_I_RTI_END 108 /* RTI returning */
|
#define CPU_I_RTI_END 108 /* RTI returning */
|
||||||
#define CPU_I_INTON 109 /* INTON servicing %s */
|
#define CPU_I_INTON 109 /* INTON servicing %s */
|
||||||
#define CPU_I_REVISION 110 /* CPU emulation revision: %s */
|
#define CPU_I_REVISION 110 /* CPU emulation revision: %s */
|
||||||
#define CPU_I_TIMER1_EX 111 /* Timer 1 expired; ctrl=%x */
|
#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_TIMER2_EX 112 /* Timer 1 expired; ctrl=%x */
|
||||||
#define CPU_I_EMULATOR_INT 113 /* Emulator interrupt req. detected */
|
#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_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_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_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_ELAPSED 117 /* 3.1: Spent %d us in idle loop */
|
||||||
#define CPU_I_HALT 118 /* 3.13: CPU halted */
|
#define CPU_I_HALT 118 /* 3.13: CPU halted */
|
||||||
#define CPU_I_RUN 119 /* 3.13: CPU running */
|
#define CPU_I_RUN 119 /* 3.13: CPU running */
|
||||||
#define CPU_W_RESETTING 201 /* Resetting CPU */
|
#define CPU_W_RESETTING 201 /* Resetting CPU */
|
||||||
#define CPU_W_BAD_MONITOR_CMD 202 /* Bad monitor command: %s */
|
#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_BAD_OPCODE 301 /* Bad opc. pc=%x, value=%x */
|
||||||
#define CPU_E_SAVE 302 /* Can't save CPU status */
|
#define CPU_E_SAVE 302 /* Can't save CPU status */
|
||||||
#define CPU_E_NO_HALT 303 /* 3.13: Halt/Run not allowed */
|
#define CPU_E_NO_HALT 303 /* 3.13: Halt/Run not allowed */
|
||||||
#define CPU_F_INTERR 401 /* Internal error %s */
|
#define CPU_F_INTERR 401 /* Internal error %s */
|
||||||
#define CPU_F_BAD_SHUTDN 402 /* Unexpected CPU shutdown */
|
#define CPU_F_BAD_SHUTDN 402 /* Unexpected CPU shutdown */
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Function prototypes
|
Function prototypes
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void CpuInit(void);
|
void CpuInit( void );
|
||||||
void CpuReset(void);
|
void CpuReset( void );
|
||||||
void CpuSave(void);
|
void CpuSave( void );
|
||||||
void OneStep(void);
|
void OneStep( void );
|
||||||
void CpuIntRequest(enum IntRequest ireq);
|
void CpuIntRequest( enum IntRequest ireq );
|
||||||
void CpuWake(void);
|
void CpuWake( void );
|
||||||
void Emulator(void);
|
void Emulator( void );
|
||||||
void EmulatorIntRequest(void);
|
void EmulatorIntRequest( void );
|
||||||
void EmulatorInit(void); /* 2.1 */
|
void EmulatorInit( void ); /* 2.1 */
|
||||||
void EmulatorExit(enum ExitOption opt); /* 2.1 */
|
void EmulatorExit( enum ExitOption opt ); /* 2.1 */
|
||||||
int CpuHaltRequest(void); /* 3.13 */
|
int CpuHaltRequest( void ); /* 3.13 */
|
||||||
int CpuRunRequest(void); /* 3.13 */
|
int CpuRunRequest( void ); /* 3.13 */
|
||||||
int CpuHaltAllowed(void); /* 3.13 */
|
int CpuHaltAllowed( void ); /* 3.13 */
|
||||||
|
|
||||||
Address Disassemble(Address pc, char ob[DISASSEMBLE_OB_SIZE]);
|
Address Disassemble( Address pc, char ob[ DISASSEMBLE_OB_SIZE ] );
|
||||||
void DumpCpuStatus(char ob[DUMP_CPU_STATUS_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 "cpu.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID DEBUG_CHF_MODULE_ID
|
#define CHF_MODULE_ID DEBUG_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Static/Global variables
|
Static/Global variables
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#ifdef DEBUG_LEVEL
|
# ifdef DEBUG_LEVEL
|
||||||
int debug_level = DEBUG_LEVEL;
|
int debug_level = DEBUG_LEVEL;
|
||||||
#else
|
# else
|
||||||
int debug_level = 0;
|
int debug_level = 0;
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
@ -105,23 +103,23 @@ int debug_level = 0;
|
||||||
it signals a condition and does nothing more.
|
it signals a condition and does nothing more.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
SetDebugLevel(new_level)
|
SetDebugLevel(new_level)
|
||||||
.input :
|
.input :
|
||||||
int new_level, new value of the debug_level flag
|
int new_level, new value of the debug_level flag
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
DEBUG_W_NOT_SUPPORTED
|
DEBUG_W_NOT_SUPPORTED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 28-Jan-1998, creation
|
1.1, 28-Jan-1998, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void SetDebugLevel(int new_level)
|
void SetDebugLevel( int new_level )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
debug_level = new_level;
|
debug_level = new_level;
|
||||||
#else
|
#else
|
||||||
ChfCondition DEBUG_W_NOT_SUPPORTED, CHF_WARNING ChfEnd;
|
ChfCondition DEBUG_W_NOT_SUPPORTED, CHF_WARNING ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
93
src/debug.h
93
src/debug.h
|
@ -44,10 +44,10 @@
|
||||||
.description :
|
.description :
|
||||||
This header defines the following macros:
|
This header defines the following macros:
|
||||||
|
|
||||||
- debug0(debug_class, condition_code)
|
- debug0(debug_class, condition_code)
|
||||||
- debug1(debug_class, condition_code, arg_1)
|
- debug1(debug_class, condition_code, arg_1)
|
||||||
- debug2(debug_class, condition_code, arg_1, arg_2)
|
- debug2(debug_class, condition_code, arg_1, arg_2)
|
||||||
- debug3(debug_class, condition_code, arg_1, arg_2, arg_3)
|
- debug3(debug_class, condition_code, arg_1, arg_2, arg_3)
|
||||||
|
|
||||||
used throughout the source code for debugging purposes.
|
used throughout the source code for debugging purposes.
|
||||||
|
|
||||||
|
@ -101,73 +101,62 @@
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
#define debug_preamble(debug_class, condition_code) \
|
# define debug_preamble( debug_class, condition_code ) \
|
||||||
{ \
|
{ \
|
||||||
extern int debug_level; \
|
extern int debug_level; \
|
||||||
if(debug_level & (debug_class)) \
|
if ( debug_level & ( debug_class ) ) { \
|
||||||
{ \
|
ChfCondition( condition_code ), CHF_INFO
|
||||||
ChfCondition (condition_code), CHF_INFO
|
|
||||||
|
|
||||||
#define debug_postamble \
|
# define debug_postamble \
|
||||||
ChfEnd; \
|
ChfEnd; \
|
||||||
ChfSignal(); \
|
ChfSignal(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define debug0(debug_class, condition_code) \
|
# define debug0( debug_class, condition_code ) debug_preamble( debug_class, condition_code ) debug_postamble
|
||||||
debug_preamble(debug_class, condition_code) \
|
|
||||||
debug_postamble
|
|
||||||
|
|
||||||
#define debug1(debug_class, condition_code, arg_1) \
|
# define debug1( debug_class, condition_code, arg_1 ) debug_preamble( debug_class, condition_code ), arg_1 debug_postamble
|
||||||
debug_preamble(debug_class, condition_code), arg_1 \
|
|
||||||
debug_postamble
|
|
||||||
|
|
||||||
#define debug2(debug_class, condition_code, arg_1, arg_2) \
|
# define debug2( debug_class, condition_code, arg_1, arg_2 ) debug_preamble( debug_class, condition_code ), arg_1, arg_2 debug_postamble
|
||||||
debug_preamble(debug_class, condition_code), arg_1, arg_2 \
|
|
||||||
debug_postamble
|
|
||||||
|
|
||||||
#define debug3(debug_class, condition_code, arg_1, arg_2, arg_3) \
|
# 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_preamble( debug_class, condition_code ), arg_1, arg_2, arg_3 debug_postamble
|
||||||
debug_postamble
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define debug0(debug_class, condition_code)
|
# define debug0( debug_class, condition_code )
|
||||||
#define debug1(debug_class, condition_code, arg_1)
|
# define debug1( debug_class, condition_code, arg_1 )
|
||||||
#define debug2(debug_class, condition_code, arg_1, arg_2)
|
# define debug2( debug_class, condition_code, arg_1, arg_2 )
|
||||||
#define debug3(debug_class, condition_code, arg_1, arg_2, arg_3)
|
# define debug3( debug_class, condition_code, arg_1, arg_2, arg_3 )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Debug classes
|
Debug classes
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define DEBUG_C_TRACE 0x8000 /* Function Call trace */
|
#define DEBUG_C_TRACE 0x8000 /* Function Call trace */
|
||||||
#define DEBUG_C_MODULES 0x4000 /* Modules configuration */
|
#define DEBUG_C_MODULES 0x4000 /* Modules configuration */
|
||||||
#define DEBUG_C_DISPLAY 0x2000 /* Display activity */
|
#define DEBUG_C_DISPLAY 0x2000 /* Display activity */
|
||||||
#define DEBUG_C_INT 0x1000 /* Interrupt activity */
|
#define DEBUG_C_INT 0x1000 /* Interrupt activity */
|
||||||
#define DEBUG_C_TIMERS 0x0800 /* Timers activity */
|
#define DEBUG_C_TIMERS 0x0800 /* Timers activity */
|
||||||
#define DEBUG_C_SERIAL 0x0400 /* 2.5: Serial port activity */
|
#define DEBUG_C_SERIAL 0x0400 /* 2.5: Serial port activity */
|
||||||
#define DEBUG_C_MOD_CACHE 0x0200 /* 2.7: Module cache */
|
#define DEBUG_C_MOD_CACHE 0x0200 /* 2.7: Module cache */
|
||||||
#define DEBUG_C_IMPLEMENTATION 0x0100 /* Feature implementation */
|
#define DEBUG_C_IMPLEMENTATION 0x0100 /* Feature implementation */
|
||||||
#define DEBUG_C_FLASH 0x0080 /* 3.3: Flash ROM */
|
#define DEBUG_C_FLASH 0x0080 /* 3.3: Flash ROM */
|
||||||
#define DEBUG_C_X_FUNC 0x0040 /* 3.13: Extended functions */
|
#define DEBUG_C_X_FUNC 0x0040 /* 3.13: Extended functions */
|
||||||
#define DEBUG_C_REVISION 0x0010 /* Revision information */
|
#define DEBUG_C_REVISION 0x0010 /* Revision information */
|
||||||
#define DEBUG_C_X11 0x0001 /* X11 Interface */
|
#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_NOT_SUPPORTED 201 /* Debug not supported */
|
||||||
#define DEBUG_W_BAD_CMD 202 /* Invalid command */
|
#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 "disk_io.h"
|
||||||
#include "debug.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>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ReadNibblesFromFile
|
.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.
|
caller a status code.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
st = ReadNibbledFromFile(name, size, dest);
|
st = ReadNibbledFromFile(name, size, dest);
|
||||||
.input :
|
.input :
|
||||||
const char *name, file name
|
const char *name, file name
|
||||||
int size, size of the file (nibbles, NOT bytes)
|
int size, size of the file (nibbles, NOT bytes)
|
||||||
.output :
|
.output :
|
||||||
Nibble *dest, pointer to the destination memory area
|
Nibble *dest, pointer to the destination memory area
|
||||||
int st, status code
|
int st, status code
|
||||||
.status_codes :
|
.status_codes :
|
||||||
DISK_IO_I_CALLED (signalled)
|
DISK_IO_I_CALLED (signalled)
|
||||||
DISK_IO_E_OPEN
|
DISK_IO_E_OPEN
|
||||||
DISK_IO_E_GETC
|
DISK_IO_E_GETC
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 11-Feb-1998, creation
|
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;
|
FILE* f;
|
||||||
int i;
|
int i;
|
||||||
int by;
|
int by;
|
||||||
int st = DISK_IO_S_OK;
|
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)
|
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)
|
|
||||||
{
|
|
||||||
ChfErrnoCondition;
|
ChfErrnoCondition;
|
||||||
ChfCondition st=DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest[i++] = (Nibble)(by & 0x0F);
|
|
||||||
dest[i++] = (Nibble)((by & 0xF0) >> 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(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
|
.title : WriteNibblesToFile
|
||||||
|
@ -155,63 +149,57 @@ int ReadNibblesFromFile(const char *name, int size, Nibble *dest)
|
||||||
It returns to the caller a status code
|
It returns to the caller a status code
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
st = WriteNibblesToFile(src, size, name);
|
st = WriteNibblesToFile(src, size, name);
|
||||||
.input :
|
.input :
|
||||||
const Nibble *src, pointer to data to be written
|
const Nibble *src, pointer to data to be written
|
||||||
int size, # of nibble to write
|
int size, # of nibble to write
|
||||||
const char *name, file name
|
const char *name, file name
|
||||||
.output :
|
.output :
|
||||||
int st, status code
|
int st, status code
|
||||||
.status_codes :
|
.status_codes :
|
||||||
DISK_IO_I_CALLED (signalled)
|
DISK_IO_I_CALLED (signalled)
|
||||||
DISK_IO_E_OPEN
|
DISK_IO_E_OPEN
|
||||||
DISK_IO_E_PUTC
|
DISK_IO_E_PUTC
|
||||||
DISK_IO_E_CLOSE
|
DISK_IO_E_CLOSE
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 11-Feb-1998, creation
|
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;
|
FILE* f;
|
||||||
int i;
|
int i;
|
||||||
int by;
|
int by;
|
||||||
int st = DISK_IO_S_OK;
|
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)
|
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)
|
|
||||||
{
|
|
||||||
ChfErrnoCondition;
|
ChfErrnoCondition;
|
||||||
ChfCondition st=DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fclose(f) == EOF)
|
else {
|
||||||
{
|
for ( i = 0; i < size; ) {
|
||||||
ChfErrnoCondition;
|
by = ( int )src[ i++ ];
|
||||||
ChfCondition st=DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
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
|
.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.
|
from the disk file 'name' and returns a status code to the caller.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
st = ReadStructFromFile(name, s_size, s);
|
st = ReadStructFromFile(name, s_size, s);
|
||||||
.input :
|
.input :
|
||||||
const char *name, file name
|
const char *name, file name
|
||||||
size_t s_size, structure size
|
size_t s_size, structure size
|
||||||
.output :
|
.output :
|
||||||
void *s, pointer to the structure
|
void *s, pointer to the structure
|
||||||
.status_codes :
|
.status_codes :
|
||||||
DISK_IO_I_CALLED (signalled)
|
DISK_IO_I_CALLED (signalled)
|
||||||
DISK_IO_E_OPEN
|
DISK_IO_E_OPEN
|
||||||
DISK_IO_E_READ
|
DISK_IO_E_READ
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 11-Feb-1998, creation
|
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;
|
FILE* f;
|
||||||
int st = DISK_IO_S_OK;
|
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)
|
if ( ( f = fopen( name, "rb" ) ) == ( FILE* )NULL ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(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
|
.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.
|
'name' and returns to the caller a status code.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
st =WriteStructToFile(s, s_size, name);
|
st =WriteStructToFile(s, s_size, name);
|
||||||
.input :
|
.input :
|
||||||
const void *s, pointer to the structure to be written
|
const void *s, pointer to the structure to be written
|
||||||
size_t s_size, structure size
|
size_t s_size, structure size
|
||||||
const char *name, output file name
|
const char *name, output file name
|
||||||
.output :
|
.output :
|
||||||
int st, status code
|
int st, status code
|
||||||
.status_codes :
|
.status_codes :
|
||||||
DISK_IO_I_CALLED (signalled)
|
DISK_IO_I_CALLED (signalled)
|
||||||
DISK_IO_E_OPEN
|
DISK_IO_E_OPEN
|
||||||
DISK_IO_E_WRITE
|
DISK_IO_E_WRITE
|
||||||
DISK_IO_E_CLOSE
|
DISK_IO_E_CLOSE
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 11-Feb-1998, creation
|
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;
|
FILE* f;
|
||||||
int st = DISK_IO_S_OK;
|
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)
|
if ( ( f = fopen( name, "wb" ) ) == ( FILE* )NULL ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||||
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(fclose(f) == EOF)
|
else {
|
||||||
{
|
if ( fwrite( s, s_size, ( size_t )1, f ) != 1 ) {
|
||||||
ChfErrnoCondition;
|
ChfErrnoCondition;
|
||||||
ChfCondition st=DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
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_S_OK 0 /* Function completed succesfully */
|
||||||
#define DISK_IO_I_CALLED 101 /* Function %s called */
|
#define DISK_IO_I_CALLED 101 /* Function %s called */
|
||||||
#define DISK_IO_E_OPEN 401 /* Open file %s failed */
|
#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_GETC 402 /* getc() from file %s failed */
|
||||||
#define DISK_IO_E_PUTC 403 /* putc() to 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_READ 404 /* fread() from file %s failed */
|
||||||
#define DISK_IO_E_WRITE 405 /* fwrite() to 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_CLOSE 406 /* Close file %s failed */
|
||||||
#define DISK_IO_E_BAD_HDR 407 /* File %s has a bad header */
|
#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_E_SIZE 408 /* File %s too large */
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Function prototypes
|
Function prototypes
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int ReadNibblesFromFile(const char *name, int size, Nibble *dest);
|
int ReadNibblesFromFile( const char* name, int size, Nibble* dest );
|
||||||
int WriteNibblesToFile(const Nibble *src, int size, const char *name);
|
int WriteNibblesToFile( const Nibble* src, int size, const char* name );
|
||||||
int ReadStructFromFile(const char *name, size_t s_size, void *s);
|
int ReadStructFromFile( const char* name, size_t s_size, void* s );
|
||||||
int WriteStructToFile(const void *s, size_t s_size, const char *name);
|
int WriteStructToFile( const void* s, size_t s_size, const char* name );
|
||||||
|
|
||||||
int ReadObjectFromFile(
|
int ReadObjectFromFile( const char* name, const char* hdr, Address start, Address end );
|
||||||
const char *name, const char *hdr, Address start, Address end);
|
int WriteObjectToFile( Address start, Address end, const char* hdr, const char* name );
|
||||||
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 "disk_io.h"
|
||||||
#include "debug.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>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ReadObjectFromFile
|
.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.
|
This function returns to the caller a status code.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
st = ReadObjectFromFile(name, hdr, start, end);
|
st = ReadObjectFromFile(name, hdr, start, end);
|
||||||
|
|
||||||
.input :
|
.input :
|
||||||
const char *name, input file name
|
const char *name, input file name
|
||||||
const char *hdr, file header
|
const char *hdr, file header
|
||||||
Address start, start address (inclusive)
|
Address start, start address (inclusive)
|
||||||
Address end, end address (exclusive)
|
Address end, end address (exclusive)
|
||||||
.output :
|
.output :
|
||||||
int st, status code
|
int st, status code
|
||||||
.status_codes :
|
.status_codes :
|
||||||
DISK_IO_I_CALLED (signalled)
|
DISK_IO_I_CALLED (signalled)
|
||||||
DISK_IO_E_OPEN
|
DISK_IO_E_OPEN
|
||||||
DISK_IO_E_GETC
|
DISK_IO_E_GETC
|
||||||
DISK_IO_E_BAD_HDR
|
DISK_IO_E_BAD_HDR
|
||||||
DISK_IO_E_SIZE
|
DISK_IO_E_SIZE
|
||||||
.notes :
|
.notes :
|
||||||
3.14, 10-Nov-2000, creation
|
3.14, 10-Nov-2000, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
int ReadObjectFromFile(
|
int ReadObjectFromFile( const char* name, const char* hdr, Address start, Address end )
|
||||||
const char *name, const char *hdr, Address start, Address end)
|
|
||||||
{
|
{
|
||||||
size_t hdr_len = strlen(hdr);
|
size_t hdr_len = strlen( hdr );
|
||||||
FILE *f;
|
FILE* f;
|
||||||
int i;
|
int i;
|
||||||
int by;
|
int by;
|
||||||
Address cur;
|
Address cur;
|
||||||
|
|
||||||
#define N_SAVE_AREA 10
|
#define N_SAVE_AREA 10
|
||||||
Nibble save_area[N_SAVE_AREA];
|
Nibble save_area[ N_SAVE_AREA ];
|
||||||
|
|
||||||
int st = DISK_IO_S_OK;
|
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 */
|
/* Save first nibbles of target space into save_area */
|
||||||
for(cur=start, i=0; cur < end && i<N_SAVE_AREA; cur++, i++)
|
for ( cur = start, i = 0; cur < end && i < N_SAVE_AREA; cur++, i++ )
|
||||||
save_area[i] = ReadNibble(cur);
|
save_area[ i ] = ReadNibble( cur );
|
||||||
|
|
||||||
if((f = fopen(name, "rb")) == (FILE *)NULL)
|
if ( ( f = fopen( name, "rb" ) ) == ( FILE* )NULL ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||||
ChfCondition st=DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Check and skip header */
|
||||||
/* Check and skip header */
|
for ( i = 0; i < hdr_len; i++ ) {
|
||||||
for(i=0; i<hdr_len; i++)
|
by = getc( f );
|
||||||
{
|
|
||||||
by = getc(f);
|
|
||||||
|
|
||||||
if(by == EOF)
|
if ( by == EOF ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition st = DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||||
ChfCondition st=DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
else if(hdr[i] != '?' && by != hdr[i])
|
else if ( hdr[ i ] != '?' && by != hdr[ i ] ) {
|
||||||
{
|
ChfCondition st = DISK_IO_E_BAD_HDR, CHF_ERROR, name ChfEnd;
|
||||||
ChfCondition st=DISK_IO_E_BAD_HDR, CHF_ERROR, name ChfEnd;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(st == DISK_IO_S_OK)
|
if ( st == DISK_IO_S_OK ) {
|
||||||
{
|
cur = start;
|
||||||
cur = start;
|
|
||||||
|
|
||||||
/* Header check/skip OK; transfer */
|
/* Header check/skip OK; transfer */
|
||||||
while((by = getc(f)) != EOF)
|
while ( ( by = getc( f ) ) != EOF ) {
|
||||||
{
|
/* Next byte available in by; check available space */
|
||||||
/* Next byte available in by; check available space */
|
if ( cur >= end - 1 ) {
|
||||||
if(cur >= end-1)
|
ChfCondition st = DISK_IO_E_SIZE, CHF_ERROR, name ChfEnd;
|
||||||
{
|
break;
|
||||||
ChfCondition st=DISK_IO_E_SIZE, CHF_ERROR, name ChfEnd;
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store it */
|
/* Store it */
|
||||||
WriteNibble(cur++, (Nibble)(by & 0x0F));
|
WriteNibble( cur++, ( Nibble )( by & 0x0F ) );
|
||||||
WriteNibble(cur++, (Nibble)((by & 0xF0) >> 4));
|
WriteNibble( cur++, ( Nibble )( ( by & 0xF0 ) >> 4 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check why getc() failed */
|
/* Check why getc() failed */
|
||||||
if(ferror(f) && !feof(f))
|
if ( ferror( f ) && !feof( f ) ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition st = DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||||
ChfCondition st=DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Recover from save_area if transfer failed */
|
/* Recover from save_area if transfer failed */
|
||||||
if(st)
|
if ( st )
|
||||||
for(cur=start, i=0; cur < end && i<N_SAVE_AREA; cur++, i++)
|
for ( cur = start, i = 0; cur < end && i < N_SAVE_AREA; cur++, i++ )
|
||||||
WriteNibble(cur, save_area[i]);
|
WriteNibble( cur, save_area[ i ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)fclose(f);
|
( void )fclose( f );
|
||||||
}
|
}
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : WriteObjectToFile
|
.title : WriteObjectToFile
|
||||||
|
@ -225,92 +213,81 @@ int ReadObjectFromFile(
|
||||||
This function returns to the caller a status code.
|
This function returns to the caller a status code.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
st = WriteObjectToFile(start, end, hdr, name);
|
st = WriteObjectToFile(start, end, hdr, name);
|
||||||
.input :
|
.input :
|
||||||
Address start, start address (inclusive)
|
Address start, start address (inclusive)
|
||||||
Address end, end address (exclusive)
|
Address end, end address (exclusive)
|
||||||
const char *hdr, file header
|
const char *hdr, file header
|
||||||
const char *name, output file name
|
const char *name, output file name
|
||||||
.output :
|
.output :
|
||||||
int st, status code
|
int st, status code
|
||||||
.status_codes :
|
.status_codes :
|
||||||
DISK_IO_I_CALLED (signalled)
|
DISK_IO_I_CALLED (signalled)
|
||||||
DISK_IO_E_OPEN
|
DISK_IO_E_OPEN
|
||||||
DISK_IO_E_PUTC
|
DISK_IO_E_PUTC
|
||||||
DISK_IO_E_CLOSE
|
DISK_IO_E_CLOSE
|
||||||
.notes :
|
.notes :
|
||||||
3.14, 10-Nov-2000, creation
|
3.14, 10-Nov-2000, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
int WriteObjectToFile(
|
int WriteObjectToFile( Address start, Address end, const char* hdr, const char* name )
|
||||||
Address start, Address end, const char *hdr, const char *name)
|
|
||||||
{
|
{
|
||||||
size_t hdr_len = strlen(hdr);
|
size_t hdr_len = strlen( hdr );
|
||||||
FILE *f;
|
FILE* f;
|
||||||
int i;
|
int i;
|
||||||
int by;
|
int by;
|
||||||
Address cur;
|
Address cur;
|
||||||
|
|
||||||
int st = DISK_IO_S_OK;
|
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)
|
if ( ( f = fopen( name, "wb" ) ) == ( FILE* )NULL ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||||
ChfCondition st=DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Write header; replace wildcard character '?' with 'S' */
|
||||||
/* Write header; replace wildcard character '?' with 'S' */
|
for ( i = 0; i < hdr_len; i++ ) {
|
||||||
for(i=0; i<hdr_len; i++)
|
if ( putc( hdr[ i ] == '?' ? 'S' : hdr[ i ], f ) == EOF ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
if(putc(hdr[i] == '?' ? 'S' : hdr[i], f) == EOF)
|
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||||
{
|
break;
|
||||||
ChfErrnoCondition;
|
}
|
||||||
ChfCondition st=DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(st == DISK_IO_S_OK)
|
if ( st == DISK_IO_S_OK ) {
|
||||||
{
|
cur = start;
|
||||||
cur = start;
|
|
||||||
|
|
||||||
while(cur < end-1)
|
while ( cur < end - 1 ) {
|
||||||
{
|
/* Make a byte with two nibbles */
|
||||||
/* Make a byte with two nibbles */
|
by = ( int )ReadNibble( cur++ );
|
||||||
by = (int)ReadNibble(cur++);
|
by |= ( int )ReadNibble( cur++ ) << 4;
|
||||||
by |= (int)ReadNibble(cur++) << 4;
|
|
||||||
|
|
||||||
if(putc(by, f) == EOF)
|
if ( putc( by, f ) == EOF ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||||
ChfCondition st=DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the last odd nibble, if necessary */
|
/* Write the last odd nibble, if necessary */
|
||||||
if(st == DISK_IO_S_OK && cur == end-1)
|
if ( st == DISK_IO_S_OK && cur == end - 1 ) {
|
||||||
{
|
by = ( int )ReadNibble( cur++ );
|
||||||
by = (int)ReadNibble(cur++);
|
|
||||||
|
|
||||||
if(putc(by, f) == EOF)
|
if ( putc( by, f ) == EOF ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||||
ChfCondition st=DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the output file anyway */
|
/* Close the output file anyway */
|
||||||
if(fclose(f) == EOF)
|
if ( fclose( f ) == EOF ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition st = DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
||||||
ChfCondition st=DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
|
|
602
src/display.c
602
src/display.c
|
@ -52,10 +52,10 @@
|
||||||
x48 source code by Eddie C. Dost (ecd@dressler.de)
|
x48 source code by Eddie C. Dost (ecd@dressler.de)
|
||||||
|
|
||||||
NOTE: In the current (r1.1) implementation, the control fields
|
NOTE: In the current (r1.1) implementation, the control fields
|
||||||
mod_status.hdw.lcd_offset and mod_status.hdw.lcd_contrast are
|
mod_status.hdw.lcd_offset and mod_status.hdw.lcd_contrast are
|
||||||
not supported. Therefore, the emulation accuracy is sometimes
|
not supported. Therefore, the emulation accuracy is sometimes
|
||||||
poor; for example, the Equation Writer does not work well with
|
poor; for example, the Equation Writer does not work well with
|
||||||
large equations.
|
large equations.
|
||||||
|
|
||||||
.include : config.h, machdep.h, cpu.h, modules.h, display.h
|
.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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h> /* 3.1: memset() */
|
#include <string.h> /* 3.1: memset() */
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#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 "x11.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID X11_CHF_MODULE_ID
|
#define CHF_MODULE_ID X11_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
#ifndef LCD_MAG
|
#ifndef LCD_MAG
|
||||||
# define LCD_MAG 2 /* 4.1.1.1: Compat. default */
|
# define LCD_MAG 2 /* 4.1.1.1: Compat. default */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NIBBLES_PER_ROW 34 /* 136 pixel total */
|
#define NIBBLES_PER_ROW 34 /* 136 pixel total */
|
||||||
#define MAX_ROWS 64 /* 64 rows total */
|
#define MAX_ROWS 64 /* 64 rows total */
|
||||||
#define N_ANN 6 /* # of annunciators */
|
#define N_ANN 6 /* # of annunciators */
|
||||||
#define LCD_X_ORIGIN 1+4*(LCD_MAG-1) /* x origin */
|
#define LCD_X_ORIGIN 1 + 4 * ( LCD_MAG - 1 ) /* x origin */
|
||||||
|
|
||||||
#if LCD_MAG==1
|
#if LCD_MAG == 1
|
||||||
# define LCD_Y_ORIGIN 14 /* y origin */
|
# define LCD_Y_ORIGIN 14 /* y origin */
|
||||||
#else
|
#else
|
||||||
# define LCD_Y_ORIGIN 20 /* y origin */
|
# define LCD_Y_ORIGIN 20 /* y origin */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 3.8: Origin and size of clip rectangle */
|
/* 3.8: Origin and size of clip rectangle */
|
||||||
#define LCD_CLIP_X_ORIGIN LCD_X_ORIGIN
|
#define LCD_CLIP_X_ORIGIN LCD_X_ORIGIN
|
||||||
#define LCD_CLIP_Y_ORIGIN 0 /* Don't clip annunciators */
|
#define LCD_CLIP_Y_ORIGIN 0 /* Don't clip annunciators */
|
||||||
#define LCD_CLIP_WIDTH 131*LCD_MAG
|
#define LCD_CLIP_WIDTH 131 * LCD_MAG
|
||||||
#define LCD_CLIP_HEIGHT LCD_Y_ORIGIN+64*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 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] =
|
static /*const*/ char nibble_bitmap_data[ NIBBLE_VALUES ][ LCD_MAG ] = {
|
||||||
{
|
#if LCD_MAG == 1
|
||||||
#if LCD_MAG==1
|
{ 0x00 }, /* ---- */
|
||||||
{ 0x00 }, /* ---- */
|
{ 0x01 }, /* *--- */
|
||||||
{ 0x01 }, /* *--- */
|
{ 0x02 }, /* -*-- */
|
||||||
{ 0x02 }, /* -*-- */
|
{ 0x03 }, /* **-- */
|
||||||
{ 0x03 }, /* **-- */
|
{ 0x04 }, /* --*- */
|
||||||
{ 0x04 }, /* --*- */
|
{ 0x05 }, /* *-*- */
|
||||||
{ 0x05 }, /* *-*- */
|
{ 0x06 }, /* -**- */
|
||||||
{ 0x06 }, /* -**- */
|
{ 0x07 }, /* ***- */
|
||||||
{ 0x07 }, /* ***- */
|
{ 0x08 }, /* ---* */
|
||||||
{ 0x08 }, /* ---* */
|
{ 0x09 }, /* *--* */
|
||||||
{ 0x09 }, /* *--* */
|
{ 0x0a }, /* -*-* */
|
||||||
{ 0x0a }, /* -*-* */
|
{ 0x0b }, /* **-* */
|
||||||
{ 0x0b }, /* **-* */
|
{ 0x0c }, /* --** */
|
||||||
{ 0x0c }, /* --** */
|
{ 0x0d }, /* *-** */
|
||||||
{ 0x0d }, /* *-** */
|
{ 0x0e }, /* -*** */
|
||||||
{ 0x0e }, /* -*** */
|
{ 0x0f } /* **** */
|
||||||
{ 0x0f } /* **** */
|
#elif LCD_MAG == 2
|
||||||
#elif LCD_MAG==2
|
{ 0x00, 0x00 }, /* ---- */
|
||||||
{ 0x00, 0x00 }, /* ---- */
|
{ 0x03, 0x03 }, /* *--- */
|
||||||
{ 0x03, 0x03 }, /* *--- */
|
{ 0x0c, 0x0c }, /* -*-- */
|
||||||
{ 0x0c, 0x0c }, /* -*-- */
|
{ 0x0f, 0x0f }, /* **-- */
|
||||||
{ 0x0f, 0x0f }, /* **-- */
|
{ 0x30, 0x30 }, /* --*- */
|
||||||
{ 0x30, 0x30 }, /* --*- */
|
{ 0x33, 0x33 }, /* *-*- */
|
||||||
{ 0x33, 0x33 }, /* *-*- */
|
{ 0x3c, 0x3c }, /* -**- */
|
||||||
{ 0x3c, 0x3c }, /* -**- */
|
{ 0x3f, 0x3f }, /* ***- */
|
||||||
{ 0x3f, 0x3f }, /* ***- */
|
{ 0xc0, 0xc0 }, /* ---* */
|
||||||
{ 0xc0, 0xc0 }, /* ---* */
|
{ 0xc3, 0xc3 }, /* *--* */
|
||||||
{ 0xc3, 0xc3 }, /* *--* */
|
{ 0xcc, 0xcc }, /* -*-* */
|
||||||
{ 0xcc, 0xcc }, /* -*-* */
|
{ 0xcf, 0xcf }, /* **-* */
|
||||||
{ 0xcf, 0xcf }, /* **-* */
|
{ 0xf0, 0xf0 }, /* --** */
|
||||||
{ 0xf0, 0xf0 }, /* --** */
|
{ 0xf3, 0xf3 }, /* *-** */
|
||||||
{ 0xf3, 0xf3 }, /* *-** */
|
{ 0xfc, 0xfc }, /* -*** */
|
||||||
{ 0xfc, 0xfc }, /* -*** */
|
{ 0xff, 0xff } /* **** */
|
||||||
{ 0xff, 0xff } /* **** */
|
|
||||||
#else
|
#else
|
||||||
# error "Bad LCD_MAG; supported values are 1 and 2"
|
# error "Bad LCD_MAG; supported values are 1 and 2"
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static /*const*/ struct
|
static /*const*/ struct {
|
||||||
{
|
int mask; /* Bit mask */
|
||||||
int mask; /* Bit mask */
|
int x, y; /* Position */
|
||||||
int x, y; /* Position */
|
int w, h; /* Width, Height */
|
||||||
int w, h; /* Width, Height */
|
char bitmap_data[ 24 ]; /* Bitmap data */
|
||||||
char bitmap_data[24]; /* Bitmap data */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ANN_X(i) (8*LCD_MAG+(22*LCD_MAG+1)*i)
|
#define ANN_X( i ) ( 8 * LCD_MAG + ( 22 * LCD_MAG + 1 ) * i )
|
||||||
#define ANN_Y(i) (1+3*(LCD_MAG-1))
|
#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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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 ann_buffer;
|
||||||
static int clean;
|
static int clean;
|
||||||
|
|
||||||
static Display *display;
|
static Display* display;
|
||||||
static Window window;
|
static Window window;
|
||||||
static GC gc;
|
static GC gc;
|
||||||
static unsigned long fg_pixel, bg_pixel;
|
static unsigned long fg_pixel, bg_pixel;
|
||||||
static unsigned int depth;
|
static unsigned int depth;
|
||||||
|
|
||||||
static Pixmap nibble_pixmap[NIBBLE_VALUES];
|
static Pixmap nibble_pixmap[ NIBBLE_VALUES ];
|
||||||
static Pixmap ann_pixmap[N_ANN];
|
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.
|
stores them into the appropriate global variables.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
InitPixmaps();
|
InitPixmaps();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
X11_I_CALLED
|
X11_I_CALLED
|
||||||
X11_F_X_ERROR
|
X11_F_X_ERROR
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 29-Jan-1998, creation
|
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 */
|
/* Initialize nibble_pixmap */
|
||||||
for(i=0; i<NIBBLE_VALUES; i++)
|
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,
|
||||||
if((nibble_pixmap[i] =
|
bg_pixel, depth ) ) == None ) {
|
||||||
XCreatePixmapFromBitmapData(
|
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||||
display, window, nibble_bitmap_data[i], 4*LCD_MAG, LCD_MAG,
|
ChfSignal();
|
||||||
fg_pixel, bg_pixel, depth
|
}
|
||||||
)) ==
|
|
||||||
None)
|
|
||||||
{
|
|
||||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize ann_pixmap */
|
/* Initialize ann_pixmap */
|
||||||
for (i=0; i<N_ANN; i++)
|
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,
|
||||||
if((ann_pixmap[i] =
|
fg_pixel, bg_pixel, depth ) ) == None ) {
|
||||||
XCreatePixmapFromBitmapData(display, window,
|
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||||
ann_data[i].bitmap_data, ann_data[i].w, ann_data[i].h,
|
ChfSignal();
|
||||||
fg_pixel, bg_pixel, depth
|
}
|
||||||
)) ==
|
|
||||||
None)
|
|
||||||
{
|
|
||||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ClearLcd
|
.title : ClearLcd
|
||||||
|
@ -331,32 +282,31 @@ static void InitPixmaps(void)
|
||||||
This function clears the Lcd screen
|
This function clears the Lcd screen
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
ClearLcd();
|
ClearLcd();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
X11_I_CALLED
|
X11_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 29-Jan-1998, creation
|
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 */
|
/* Clear Lcd display */
|
||||||
(void)memset((void *)lcd_buffer, 0, sizeof(lcd_buffer));
|
( void )memset( ( void* )lcd_buffer, 0, sizeof( lcd_buffer ) );
|
||||||
ann_buffer = 0;
|
ann_buffer = 0;
|
||||||
|
|
||||||
XClearWindow(display, window);
|
XClearWindow( display, window );
|
||||||
XFlush(display);
|
XFlush( display );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Public funcitons
|
Public funcitons
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
@ -369,86 +319,79 @@ static void ClearLcd(void)
|
||||||
The LCD screen is initially cleared.
|
The LCD screen is initially cleared.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
InitLcd(lcd_display, lcd_window, lcd_fg_pixel, lcd_bg_pixel);
|
InitLcd(lcd_display, lcd_window, lcd_fg_pixel, lcd_bg_pixel);
|
||||||
.input :
|
.input :
|
||||||
Display *lcd_display, X display
|
Display *lcd_display, X display
|
||||||
Window lcd_window, X window to be used for display
|
Window lcd_window, X window to be used for display
|
||||||
unsigned long lcd_fg_pixel, foreground color to be used
|
unsigned long lcd_fg_pixel, foreground color to be used
|
||||||
unsigned long lcd_bg_pixel, background color to be used
|
unsigned long lcd_bg_pixel, background color to be used
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
X11_I_CALLED
|
X11_I_CALLED
|
||||||
X11_F_X_ERROR
|
X11_F_X_ERROR
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 29-Jan-1998, creation
|
1.1, 29-Jan-1998, creation
|
||||||
3.8, 23-Oct-2000, bug fix:
|
3.8, 23-Oct-2000, bug fix:
|
||||||
- added clip rectangle to GC, to avoid drawing non-existent pixels.
|
- added clip rectangle to GC, to avoid drawing non-existent pixels.
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void InitLcd(Display *lcd_display, Window lcd_window,
|
void InitLcd( Display* lcd_display, Window lcd_window, unsigned long lcd_fg_pixel, unsigned long lcd_bg_pixel )
|
||||||
unsigned long lcd_fg_pixel, unsigned long lcd_bg_pixel)
|
|
||||||
{
|
{
|
||||||
XWindowAttributes xwa;
|
XWindowAttributes xwa;
|
||||||
XGCValues gc_values;
|
XGCValues gc_values;
|
||||||
|
|
||||||
debug1(DEBUG_C_TRACE, X11_I_CALLED, "InitLcdWindow");
|
debug1( DEBUG_C_TRACE, X11_I_CALLED, "InitLcdWindow" );
|
||||||
|
|
||||||
display = lcd_display;
|
display = lcd_display;
|
||||||
window = lcd_window;
|
window = lcd_window;
|
||||||
fg_pixel = lcd_fg_pixel;
|
fg_pixel = lcd_fg_pixel;
|
||||||
bg_pixel = lcd_bg_pixel;
|
bg_pixel = lcd_bg_pixel;
|
||||||
|
|
||||||
/* Get window attributes and initialize window depth */
|
/* Get window attributes and initialize window depth */
|
||||||
if(XGetWindowAttributes(display, window, &xwa) == 0)
|
if ( XGetWindowAttributes( display, window, &xwa ) == 0 ) {
|
||||||
{
|
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
depth = xwa.depth;
|
depth = xwa.depth;
|
||||||
|
|
||||||
/* Create GC */
|
/* Create GC */
|
||||||
gc_values.function = GXcopy;
|
gc_values.function = GXcopy;
|
||||||
gc_values.plane_mask = AllPlanes;
|
gc_values.plane_mask = AllPlanes;
|
||||||
gc_values.subwindow_mode = IncludeInferiors;
|
gc_values.subwindow_mode = IncludeInferiors;
|
||||||
gc_values.foreground = lcd_fg_pixel;
|
gc_values.foreground = lcd_fg_pixel;
|
||||||
gc_values.background = lcd_bg_pixel;
|
gc_values.background = lcd_bg_pixel;
|
||||||
gc_values.graphics_exposures = False;
|
gc_values.graphics_exposures = False;
|
||||||
|
|
||||||
gc = XCreateGC(display, window,
|
gc = XCreateGC( display, window, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCSubwindowMode | GCGraphicsExposures,
|
||||||
GCFunction|GCPlaneMask|GCForeground|GCBackground|GCSubwindowMode|
|
&gc_values );
|
||||||
GCGraphicsExposures,
|
|
||||||
&gc_values);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* 3.8: This clip rectangle prevents XCopyArea() (in DrawLcd()) from
|
/* 3.8: This clip rectangle prevents XCopyArea() (in DrawLcd()) from
|
||||||
drawing non-visible pixels
|
drawing non-visible pixels
|
||||||
*/
|
*/
|
||||||
XRectangle rect[1];
|
XRectangle rect[ 1 ];
|
||||||
|
|
||||||
rect[0].x = LCD_CLIP_X_ORIGIN; /* This is the clip rectangle */
|
rect[ 0 ].x = LCD_CLIP_X_ORIGIN; /* This is the clip rectangle */
|
||||||
rect[0].y = LCD_CLIP_Y_ORIGIN;
|
rect[ 0 ].y = LCD_CLIP_Y_ORIGIN;
|
||||||
rect[0].width = LCD_CLIP_WIDTH;
|
rect[ 0 ].width = LCD_CLIP_WIDTH;
|
||||||
rect[0].height = LCD_CLIP_HEIGHT;
|
rect[ 0 ].height = LCD_CLIP_HEIGHT;
|
||||||
|
|
||||||
XSetClipRectangles(
|
XSetClipRectangles( display, gc, 0, 0, /* Alsolute clip X,Y origin */
|
||||||
display, gc,
|
rect, 1, YXBanded );
|
||||||
0, 0, /* Alsolute clip X,Y origin */
|
}
|
||||||
rect, 1, YXBanded);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize Pixmaps */
|
/* Initialize Pixmaps */
|
||||||
InitPixmaps();
|
InitPixmaps();
|
||||||
|
|
||||||
/* Clear screen and initialize the static memory areas */
|
/* Clear screen and initialize the static memory areas */
|
||||||
ClearLcd();
|
ClearLcd();
|
||||||
|
|
||||||
/* Set the 'display is clean' flag */
|
/* Set the 'display is clean' flag */
|
||||||
clean = 1;
|
clean = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : DrawLcd
|
.title : DrawLcd
|
||||||
|
@ -459,146 +402,113 @@ void InitLcd(Display *lcd_display, Window lcd_window,
|
||||||
the mod_status.hdw structure.
|
the mod_status.hdw structure.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
DrawLcd();
|
DrawLcd();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
X11_I_CALLED
|
X11_I_CALLED
|
||||||
X11_I_LCD_PAR
|
X11_I_LCD_PAR
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 29-Jan-1998, creation
|
1.1, 29-Jan-1998, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void DrawLcd(void)
|
void DrawLcd( void )
|
||||||
{
|
{
|
||||||
Address addr = mod_status.hdw.lcd_base_addr;
|
Address addr = mod_status.hdw.lcd_base_addr;
|
||||||
int y, x;
|
int y, x;
|
||||||
Nibble v;
|
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
|
/* If the debug class DEBUG_C_DISPLAY is enabled, print the display
|
||||||
parameters
|
parameters
|
||||||
*/
|
*/
|
||||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_base_addr",
|
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_base_addr", ( int )mod_status.hdw.lcd_base_addr );
|
||||||
(int)mod_status.hdw.lcd_base_addr);
|
|
||||||
|
|
||||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_on",
|
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_on", ( int )mod_status.hdw.lcd_on );
|
||||||
(int)mod_status.hdw.lcd_on);
|
|
||||||
|
|
||||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_contrast",
|
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_contrast", ( int )mod_status.hdw.lcd_contrast );
|
||||||
(int)mod_status.hdw.lcd_contrast);
|
|
||||||
|
|
||||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_vlc",
|
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_vlc", ( int )mod_status.hdw.lcd_vlc );
|
||||||
(int)mod_status.hdw.lcd_vlc);
|
|
||||||
|
|
||||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_offset",
|
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_offset", ( int )mod_status.hdw.lcd_offset );
|
||||||
(int)mod_status.hdw.lcd_offset);
|
|
||||||
|
|
||||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_line_offset",
|
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_line_offset", ( int )mod_status.hdw.lcd_line_offset );
|
||||||
(int)mod_status.hdw.lcd_line_offset);
|
|
||||||
|
|
||||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_menu_addr",
|
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_menu_addr", ( int )mod_status.hdw.lcd_menu_addr );
|
||||||
(int)mod_status.hdw.lcd_menu_addr);
|
|
||||||
|
|
||||||
debug2(DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_ann",
|
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_ann", ( int )mod_status.hdw.lcd_ann );
|
||||||
(int)mod_status.hdw.lcd_ann);
|
|
||||||
|
|
||||||
/* Check if display is on */
|
/* Check if display is on */
|
||||||
if(!mod_status.hdw.lcd_on)
|
if ( !mod_status.hdw.lcd_on ) {
|
||||||
{
|
/* Display is off; clear lcd if necessary */
|
||||||
/* Display is off; clear lcd if necessary */
|
if ( !clean ) {
|
||||||
if(!clean)
|
/* Set the 'display is clean' flag and clear the screen */
|
||||||
{
|
clean = 1;
|
||||||
/* Set the 'display is clean' flag and clear the screen */
|
ClearLcd();
|
||||||
clean = 1;
|
}
|
||||||
ClearLcd();
|
return;
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
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;
|
/* The display is on and will be no longer clean */
|
||||||
}
|
clean = 0;
|
||||||
|
|
||||||
/* Scan menu display rows */
|
/* Scan active display rows */
|
||||||
addr = mod_status.hdw.lcd_menu_addr;
|
for ( y = 0; y <= mod_status.hdw.lcd_vlc; y++ ) {
|
||||||
for(; y<MAX_ROWS; y++)
|
/* Scan columns */
|
||||||
{
|
for ( x = 0; x < NIBBLES_PER_ROW; x++ ) {
|
||||||
/* Scan columns */
|
v = FetchNibble( addr++ );
|
||||||
for(x=0; x<NIBBLES_PER_ROW; x++)
|
if ( v != lcd_buffer[ y ][ x ] ) {
|
||||||
{
|
lcd_buffer[ y ][ x ] = v;
|
||||||
v = FetchNibble(addr++);
|
|
||||||
if( v != lcd_buffer[y][x] )
|
XCopyArea( display, nibble_pixmap[ ( int )v ], window, gc, 0, 0, /* src_x, src_y */
|
||||||
{
|
4 * LCD_MAG, LCD_MAG, /* width, height */
|
||||||
lcd_buffer[y][x] = v;
|
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,
|
addr += mod_status.hdw.lcd_line_offset;
|
||||||
y*LCD_MAG + LCD_Y_ORIGIN
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Scan annunciators */
|
/* Scan menu display rows */
|
||||||
if(mod_status.hdw.lcd_ann != ann_buffer)
|
addr = mod_status.hdw.lcd_menu_addr;
|
||||||
{
|
for ( ; y < MAX_ROWS; y++ ) {
|
||||||
ann_buffer = mod_status.hdw.lcd_ann;
|
/* Scan columns */
|
||||||
|
for ( x = 0; x < NIBBLES_PER_ROW; x++ ) {
|
||||||
for(y=0; y<N_ANN; y++)
|
v = FetchNibble( addr++ );
|
||||||
{
|
if ( v != lcd_buffer[ y ][ x ] ) {
|
||||||
if((ann_buffer & ann_data[y].mask) == ann_data[y].mask)
|
lcd_buffer[ y ][ x ] = v;
|
||||||
{
|
XCopyArea( display, nibble_pixmap[ ( int )v ], window, gc, 0, 0, /* src_x, src_y */
|
||||||
XCopyArea(display, ann_pixmap[y], window, gc,
|
4 * LCD_MAG, LCD_MAG, /* width, height */
|
||||||
0, 0, /* src_x, src_y */
|
x * 4 * LCD_MAG + LCD_X_ORIGIN, y * LCD_MAG + LCD_Y_ORIGIN );
|
||||||
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 */
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Flush display */
|
/* Scan annunciators */
|
||||||
XFlush(display);
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : RefreshLcd
|
.title : RefreshLcd
|
||||||
|
@ -608,21 +518,21 @@ void DrawLcd(void)
|
||||||
This function refreshes the Lcd screen after a X Window Expose event.
|
This function refreshes the Lcd screen after a X Window Expose event.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RefreshLcd();
|
RefreshLcd();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
X11_I_CALLED
|
X11_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 17-Feb-1998, creation
|
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();
|
ClearLcd();
|
||||||
DrawLcd();
|
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,
|
void InitLcd( Display* lcd_display, Window lcd_window, unsigned long lcd_fg_pixel, unsigned long lcd_bg_pixel );
|
||||||
unsigned long lcd_fg_pixel, unsigned long lcd_bg_pixel);
|
|
||||||
|
|
||||||
void DrawLcd(void);
|
void DrawLcd( void );
|
||||||
void RefreshLcd(void);
|
void RefreshLcd( void );
|
||||||
|
|
651
src/emulator.c
651
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 "args.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID CPU_CHF_MODULE_ID
|
#define CHF_MODULE_ID CPU_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Private macros / variables / functions
|
Private macros / variables / functions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define T1_MULTIPLIER (8192/16) /* T2/T1 increment ratio */
|
#define T1_MULTIPLIER ( 8192 / 16 ) /* T2/T1 increment ratio */
|
||||||
#define T1_INTERVAL 62500 /* us per T1 increment */
|
#define T1_INTERVAL 62500 /* us per T1 increment */
|
||||||
#define T2_INTERVAL 122 /* us per T2 increment */
|
#define T2_INTERVAL 122 /* us per T2 increment */
|
||||||
|
|
||||||
/* 3.1: MAX_IDLE_X_LOOP_TIMEOUT must be low enough to prevent overflow
|
/* 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
|
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
|
module will support asynchronous selection on pty fd and will
|
||||||
be able to interact with the GUI's select mechanism.
|
be able to interact with the GUI's select mechanism.
|
||||||
*/
|
*/
|
||||||
#define T1_MS_MULTIPLIER 63 /* 3.1: Milliseconds per T1 tick (~) */
|
#define T1_MS_MULTIPLIER 63 /* 3.1: Milliseconds per T1 tick (~) */
|
||||||
#define T2_MS_DIVISOR 8 /* 3.1: T2 ticks per millisecond (~) */
|
#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 MAX_IDLE_X_LOOP_TIMEOUT 1000 /* 3.1: Max timeout for IdleXLoop() */
|
||||||
|
|
||||||
#define T1_OVF_MASK NIBBLE_MASK /* 3.1: Timer overflow masks */
|
#define T1_OVF_MASK NIBBLE_MASK /* 3.1: Timer overflow masks */
|
||||||
#define T2_OVF_MASK 0xFFFFFFFF
|
#define T2_OVF_MASK 0xFFFFFFFF
|
||||||
|
|
||||||
#define LCD_T1_MASK 0x3 /* LCD refresh timing mask */
|
#define LCD_T1_MASK 0x3 /* LCD refresh timing mask */
|
||||||
#define INT_T1_MASK 0xF /* Int. req. 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,
|
/* This function contains the main emulator loop; under normal conditions,
|
||||||
it never returns to the caller. The only way to exit this function is
|
it never returns to the caller. The only way to exit this function is
|
||||||
to signal a Chf condition that triggers an unwind operation.
|
to signal a Chf condition that triggers an unwind operation.
|
||||||
*/
|
*/
|
||||||
static void EmulatorLoop(void)
|
static void EmulatorLoop( void )
|
||||||
{
|
{
|
||||||
struct timeval old_t, cur_t;
|
struct timeval old_t, cur_t;
|
||||||
int ela;
|
int ela;
|
||||||
int inner_loop = cpu_status.inner_loop;
|
int inner_loop = cpu_status.inner_loop;
|
||||||
int t1_count = 0;
|
int t1_count = 0;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
debug1(DEBUG_C_TRACE, CPU_I_CALLED, "EmulatorLoop");
|
debug1( DEBUG_C_TRACE, CPU_I_CALLED, "EmulatorLoop" );
|
||||||
|
|
||||||
/* Ignore past interrupt requests */
|
/* Ignore past interrupt requests */
|
||||||
emulator_int_req = 0;
|
emulator_int_req = 0;
|
||||||
|
|
||||||
/* Get current time of day */
|
/* Get current time of day */
|
||||||
gettimeofday(&old_t, NULL);
|
gettimeofday( &old_t, NULL );
|
||||||
|
|
||||||
while(1)
|
while ( 1 ) {
|
||||||
{
|
/* T1 loop */
|
||||||
/* T1 loop */
|
for ( j = 0; j < T1_MULTIPLIER; j++ ) {
|
||||||
for(j=0; j<T1_MULTIPLIER; j++)
|
/* Inner loop */
|
||||||
{
|
for ( i = 0; i < inner_loop; i++ )
|
||||||
/* Inner loop */
|
OneStep();
|
||||||
for(i=0; i<inner_loop; i++) OneStep();
|
|
||||||
|
|
||||||
/* T2 update */
|
/* T2 update */
|
||||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_TRUN)
|
if ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) {
|
||||||
{
|
if ( --mod_status.hdw.t2_val == 0xFFFFFFFF ) {
|
||||||
if(--mod_status.hdw.t2_val == 0xFFFFFFFF)
|
debug1( DEBUG_C_TIMERS, CPU_I_TIMER2_EX, mod_status.hdw.t2_ctrl );
|
||||||
{
|
|
||||||
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)
|
if ( mod_status.hdw.t2_ctrl & T2_CTRL_WAKE )
|
||||||
CpuWake();
|
CpuWake();
|
||||||
|
|
||||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_INT)
|
if ( mod_status.hdw.t2_ctrl & T2_CTRL_INT )
|
||||||
CpuIntRequest(INT_REQUEST_IRQ);
|
CpuIntRequest( INT_REQUEST_IRQ );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* T1 update */
|
/* T1 update */
|
||||||
mod_status.hdw.t1_val = (mod_status.hdw.t1_val - 1) & NIBBLE_MASK;
|
mod_status.hdw.t1_val = ( mod_status.hdw.t1_val - 1 ) & NIBBLE_MASK;
|
||||||
if(mod_status.hdw.t1_val == 0xF)
|
if ( mod_status.hdw.t1_val == 0xF ) {
|
||||||
{
|
debug1( DEBUG_C_TIMERS, CPU_I_TIMER1_EX, mod_status.hdw.t1_ctrl );
|
||||||
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)
|
if ( mod_status.hdw.t1_ctrl & T1_CTRL_WAKE )
|
||||||
CpuWake();
|
CpuWake();
|
||||||
|
|
||||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_INT)
|
if ( mod_status.hdw.t1_ctrl & T1_CTRL_INT )
|
||||||
CpuIntRequest(INT_REQUEST_IRQ);
|
CpuIntRequest( INT_REQUEST_IRQ );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LCD update */
|
/* LCD update */
|
||||||
if((t1_count++ & LCD_T1_MASK) == 0) DrawLcd();
|
if ( ( t1_count++ & LCD_T1_MASK ) == 0 )
|
||||||
|
DrawLcd();
|
||||||
|
|
||||||
/* Emulator Interrupt Request */
|
/* Emulator Interrupt Request */
|
||||||
if((t1_count & INT_T1_MASK) == 0 && emulator_int_req)
|
if ( ( t1_count & INT_T1_MASK ) == 0 && emulator_int_req ) {
|
||||||
{
|
ChfCondition CPU_I_EMULATOR_INT, CHF_INFO ChfEnd;
|
||||||
ChfCondition CPU_I_EMULATOR_INT, CHF_INFO ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* X Events handling */
|
/* X Events handling */
|
||||||
HandleXEvents();
|
HandleXEvents();
|
||||||
|
|
||||||
/* Handle serial port */
|
/* Handle serial port */
|
||||||
HandleSerial();
|
HandleSerial();
|
||||||
|
|
||||||
/* Adjust inner_loop limit */
|
/* Adjust inner_loop limit */
|
||||||
gettimeofday(&cur_t, NULL);
|
gettimeofday( &cur_t, NULL );
|
||||||
|
|
||||||
ela = (cur_t.tv_sec - old_t.tv_sec) * 1000000 +
|
ela = ( cur_t.tv_sec - old_t.tv_sec ) * 1000000 + ( cur_t.tv_usec - old_t.tv_usec );
|
||||||
(cur_t.tv_usec - old_t.tv_usec);
|
|
||||||
|
|
||||||
inner_loop = inner_loop * T1_INTERVAL / ela;
|
inner_loop = inner_loop * T1_INTERVAL / ela;
|
||||||
if(inner_loop < INNER_LOOP_MIN) inner_loop = INNER_LOOP_MIN;
|
if ( inner_loop < INNER_LOOP_MIN )
|
||||||
|
inner_loop = INNER_LOOP_MIN;
|
||||||
|
|
||||||
#ifdef REAL_CPU_SPEED
|
#ifdef REAL_CPU_SPEED
|
||||||
/* 3.13: Force an upper limit to the CPU speed if the compile-time option
|
/* 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
|
REAL_CPU_SPEED is defined: inner_loop is limited to
|
||||||
cpu_status.inner_loop_max
|
cpu_status.inner_loop_max
|
||||||
and the excess time, if any, is spent sleeping; usleep() is
|
and the excess time, if any, is spent sleeping; usleep() is
|
||||||
BSD 4.3-specific, but most recent systems should offer it anyway,
|
BSD 4.3-specific, but most recent systems should offer it anyway,
|
||||||
well, I hope.
|
well, I hope.
|
||||||
The special value cpu_status.inner_loop_max==0 gives maximum speed.
|
The special value cpu_status.inner_loop_max==0 gives maximum speed.
|
||||||
*/
|
*/
|
||||||
if(cpu_status.inner_loop_max != 0
|
if ( cpu_status.inner_loop_max != 0 && inner_loop >= cpu_status.inner_loop_max ) {
|
||||||
&& inner_loop >= cpu_status.inner_loop_max)
|
inner_loop = cpu_status.inner_loop_max;
|
||||||
{
|
if ( T1_INTERVAL > ela )
|
||||||
inner_loop = cpu_status.inner_loop_max;
|
usleep( T1_INTERVAL - ela );
|
||||||
if(T1_INTERVAL > ela) usleep(T1_INTERVAL - ela);
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cpu_status.inner_loop = inner_loop;
|
cpu_status.inner_loop = inner_loop;
|
||||||
old_t = cur_t;
|
old_t = cur_t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Condition handler for the EmulatorLoop */
|
/* Condition handler for the EmulatorLoop */
|
||||||
static ChfAction EmulatorLoopHandler(
|
static ChfAction EmulatorLoopHandler( const ChfDescriptor* d, const ChfState s, ChfPointer ctx )
|
||||||
const ChfDescriptor *d,
|
|
||||||
const ChfState s,
|
|
||||||
ChfPointer ctx
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ChfAction act;
|
ChfAction act;
|
||||||
|
|
||||||
/* Check Chf state */
|
/* Check Chf state */
|
||||||
switch(s)
|
switch ( s ) {
|
||||||
{
|
/* 2.1: Chf release 2 fixed the spelling of 'SIGNALING' */
|
||||||
/* 2.1: Chf release 2 fixed the spelling of 'SIGNALING' */
|
case CHF_SIGNALING:
|
||||||
case CHF_SIGNALING:
|
/* ChfSignal() in progress */
|
||||||
/* ChfSignal() in progress */
|
if ( ChfGetModuleId( d ) == CPU_CHF_MODULE_ID ) {
|
||||||
if(ChfGetModuleId(d) == CPU_CHF_MODULE_ID)
|
/* Condition from CPU modules; check Condition Code */
|
||||||
{
|
switch ( ChfGetConditionCode( d ) ) {
|
||||||
/* Condition from CPU modules; check Condition Code */
|
|
||||||
switch(ChfGetConditionCode(d))
|
|
||||||
{
|
|
||||||
#ifdef CPU_SPIN_SHUTDN
|
#ifdef CPU_SPIN_SHUTDN
|
||||||
case CPU_I_SHUTDN:
|
case CPU_I_SHUTDN:
|
||||||
/* CPU shutdown signalled with CPU_SPIN_SHUTDN defined;
|
/* CPU shutdown signalled with CPU_SPIN_SHUTDN defined;
|
||||||
Fatal error.
|
Fatal error.
|
||||||
*/
|
*/
|
||||||
ChfCondition CPU_F_BAD_SHUTDN, CHF_FATAL ChfEnd;
|
ChfCondition CPU_F_BAD_SHUTDN, CHF_FATAL ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
act = CHF_RESIGNAL;
|
act = CHF_RESIGNAL;
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
case CPU_I_SHUTDN:
|
case CPU_I_SHUTDN:
|
||||||
{
|
{
|
||||||
/* 3.1: CPU_SPIN_SHUTDN is not defined, and the cpu emulator
|
/* 3.1: CPU_SPIN_SHUTDN is not defined, and the cpu emulator
|
||||||
has just executed a shutdown instruction.
|
has just executed a shutdown instruction.
|
||||||
Let's do something a little tricky here:
|
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
|
3- determine which timer will expire first, and
|
||||||
compute an approximate value of the maximum duration
|
compute an approximate value of the maximum duration
|
||||||
of the shutdown --> ms
|
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
|
5- enter the inner idle loop; it breaks when either an
|
||||||
X Event occurred (possibly clearing the shutdown) or
|
X Event occurred (possibly clearing the shutdown) or
|
||||||
the shutdown timeout elapses
|
the shutdown timeout elapses
|
||||||
|
|
||||||
6- determine the actual time we spend in the idle loop
|
6- determine the actual time we spend in the idle loop
|
||||||
(X timeouts are not accurate enough for this purpose)
|
(X timeouts are not accurate enough for this purpose)
|
||||||
|
|
||||||
7- update T1 and T2, check their state and wake/interrupt
|
7- update T1 and T2, check their state and wake/interrupt
|
||||||
the CPU if necessary
|
the CPU if necessary
|
||||||
|
|
||||||
Activities 3-7 above are enclosed in an outer loop because we
|
Activities 3-7 above are enclosed in an outer loop because we
|
||||||
cannot be absolutely sure of the actual time spent
|
cannot be absolutely sure of the actual time spent
|
||||||
in the idle loop; moreover, not all X Events actually
|
in the idle loop; moreover, not all X Events actually
|
||||||
spool up the CPU. The outer loop breaks when the CPU is
|
spool up the CPU. The outer loop breaks when the CPU is
|
||||||
actually brought out of shutdown.
|
actually brought out of shutdown.
|
||||||
|
|
||||||
frac_t1 and frac_t2 contain the number of microseconds
|
frac_t1 and frac_t2 contain the number of microseconds
|
||||||
not accounted for in the last T1/T2 update, respectively;
|
not accounted for in the last T1/T2 update, respectively;
|
||||||
they help minimize the cumulative timing error induced
|
they help minimize the cumulative timing error induced
|
||||||
by executing the outer idle loop more than once.
|
by executing the outer idle loop more than once.
|
||||||
*/
|
*/
|
||||||
struct timeval start_idle, end_idle;
|
struct timeval start_idle, end_idle;
|
||||||
int frac_t1=0, frac_t2=0;
|
int frac_t1 = 0, frac_t2 = 0;
|
||||||
|
|
||||||
gettimeofday(&start_idle, NULL);
|
gettimeofday( &start_idle, NULL );
|
||||||
|
|
||||||
/* Redraw the LCD immediately before entering idle loop;
|
/* Redraw the LCD immediately before entering idle loop;
|
||||||
this ensures that the latest LCD updated actually
|
this ensures that the latest LCD updated actually
|
||||||
get to the screen.
|
get to the screen.
|
||||||
*/
|
*/
|
||||||
DrawLcd();
|
DrawLcd();
|
||||||
|
|
||||||
/* Handle serial port activity before entering the outer idle
|
/* Handle serial port activity before entering the outer idle
|
||||||
loop, because this could possibly bring the cpu out of
|
loop, because this could possibly bring the cpu out of
|
||||||
shutdown right now.
|
shutdown right now.
|
||||||
*/
|
*/
|
||||||
HandleSerial();
|
HandleSerial();
|
||||||
|
|
||||||
/* XXX
|
/* XXX
|
||||||
If either timer has a pending service request,
|
If either timer has a pending service request,
|
||||||
process it immediately. It is not clear why it was
|
process it immediately. It is not clear why it was
|
||||||
not processed *before* shutdown, though.
|
not processed *before* shutdown, though.
|
||||||
*/
|
*/
|
||||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_SREQ)
|
if ( mod_status.hdw.t1_ctrl & T1_CTRL_SREQ ) {
|
||||||
{
|
if ( mod_status.hdw.t1_ctrl & T1_CTRL_WAKE )
|
||||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_WAKE)
|
CpuWake();
|
||||||
CpuWake();
|
|
||||||
|
|
||||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_INT)
|
if ( mod_status.hdw.t1_ctrl & T1_CTRL_INT )
|
||||||
CpuIntRequest(INT_REQUEST_IRQ);
|
CpuIntRequest( INT_REQUEST_IRQ );
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_SREQ)
|
if ( mod_status.hdw.t2_ctrl & T2_CTRL_SREQ ) {
|
||||||
{
|
if ( mod_status.hdw.t2_ctrl & T2_CTRL_WAKE )
|
||||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_WAKE)
|
CpuWake();
|
||||||
CpuWake();
|
|
||||||
|
|
||||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_INT)
|
if ( mod_status.hdw.t2_ctrl & T2_CTRL_INT )
|
||||||
CpuIntRequest(INT_REQUEST_IRQ);
|
CpuIntRequest( INT_REQUEST_IRQ );
|
||||||
}
|
}
|
||||||
|
|
||||||
while(cpu_status.shutdn)
|
while ( cpu_status.shutdn ) {
|
||||||
{
|
unsigned long ms = MAX_IDLE_X_LOOP_TIMEOUT;
|
||||||
unsigned long ms = MAX_IDLE_X_LOOP_TIMEOUT;
|
unsigned long mst;
|
||||||
unsigned long mst;
|
int ela;
|
||||||
int ela;
|
int ela_ticks;
|
||||||
int ela_ticks;
|
|
||||||
|
|
||||||
debug3(DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (during SHUTDN)",
|
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (during SHUTDN)", mod_status.hdw.t1_ctrl,
|
||||||
mod_status.hdw.t1_ctrl, mod_status.hdw.t1_val);
|
mod_status.hdw.t1_val );
|
||||||
debug3(DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T2 (during SHUTDN)",
|
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T2 (during SHUTDN)", mod_status.hdw.t2_ctrl,
|
||||||
mod_status.hdw.t2_ctrl, mod_status.hdw.t2_val);
|
mod_status.hdw.t2_val );
|
||||||
|
|
||||||
/* Determine which timer will expire first */
|
/* Determine which timer will expire first */
|
||||||
if(mod_status.hdw.t1_ctrl & (T1_CTRL_INT|T1_CTRL_WAKE))
|
if ( mod_status.hdw.t1_ctrl & ( T1_CTRL_INT | T1_CTRL_WAKE ) ) {
|
||||||
{
|
/* T1 will do something on expiration */
|
||||||
/* T1 will do something on expiration */
|
mst = ( ( unsigned long )mod_status.hdw.t1_val + 1 ) * T1_MS_MULTIPLIER;
|
||||||
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)
|
if ( ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) &&
|
||||||
&& (mod_status.hdw.t2_ctrl & (T2_CTRL_INT|T2_CTRL_WAKE)))
|
( mod_status.hdw.t2_ctrl & ( T2_CTRL_INT | T2_CTRL_WAKE ) ) ) {
|
||||||
{
|
/* T2 is running and will do something on expiration */
|
||||||
/* T2 is running and will do something on expiration */
|
mst = ( ( unsigned long )mod_status.hdw.t2_val + 1 ) / T2_MS_DIVISOR;
|
||||||
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
|
/* Handle serial port activities at each iteration of
|
||||||
the outer idle loop; this ensures that the serial
|
the outer idle loop; this ensures that the serial
|
||||||
port emulation will not starve.
|
port emulation will not starve.
|
||||||
*/
|
*/
|
||||||
HandleSerial();
|
HandleSerial();
|
||||||
|
|
||||||
/* Enter idle loop, possibly with timeout;
|
/* Enter idle loop, possibly with timeout;
|
||||||
The loop breaks when:
|
The loop breaks when:
|
||||||
- any X Event occurs (possibly clearing the shutdown)
|
- any X Event occurs (possibly clearing the shutdown)
|
||||||
- the given timeout expires
|
- the given timeout expires
|
||||||
*/
|
*/
|
||||||
debug1(DEBUG_C_TIMERS, CPU_I_IDLE_X_LOOP, ms);
|
debug1( DEBUG_C_TIMERS, CPU_I_IDLE_X_LOOP, ms );
|
||||||
IdleXLoop(ms);
|
IdleXLoop( ms );
|
||||||
|
|
||||||
/* End of idle loop; compute actual elapsed time */
|
/* End of idle loop; compute actual elapsed time */
|
||||||
gettimeofday(&end_idle, NULL);
|
gettimeofday( &end_idle, NULL );
|
||||||
|
|
||||||
ela = (end_idle.tv_sec - start_idle.tv_sec) * 1000000 +
|
ela = ( end_idle.tv_sec - start_idle.tv_sec ) * 1000000 + ( end_idle.tv_usec - start_idle.tv_usec );
|
||||||
(end_idle.tv_usec - start_idle.tv_usec);
|
|
||||||
|
|
||||||
/* Update start_idle here to contain lag */
|
/* Update start_idle here to contain lag */
|
||||||
start_idle = end_idle;
|
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 */
|
/* Update timers and act accordingly */
|
||||||
ela_ticks = ((ela+frac_t1) + T1_INTERVAL/2) / T1_INTERVAL;
|
ela_ticks = ( ( ela + frac_t1 ) + T1_INTERVAL / 2 ) / T1_INTERVAL;
|
||||||
frac_t1 = (ela+frac_t1) - ela_ticks * T1_INTERVAL;
|
frac_t1 = ( ela + frac_t1 ) - ela_ticks * T1_INTERVAL;
|
||||||
|
|
||||||
if(ela_ticks > mod_status.hdw.t1_val)
|
if ( ela_ticks > mod_status.hdw.t1_val ) {
|
||||||
{
|
debug1( DEBUG_C_TIMERS, CPU_I_TIMER1_EX, mod_status.hdw.t1_ctrl );
|
||||||
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)
|
if ( mod_status.hdw.t1_ctrl & T1_CTRL_WAKE )
|
||||||
CpuWake();
|
CpuWake();
|
||||||
|
|
||||||
if(mod_status.hdw.t1_ctrl & T1_CTRL_INT)
|
if ( mod_status.hdw.t1_ctrl & T1_CTRL_INT )
|
||||||
CpuIntRequest(INT_REQUEST_IRQ);
|
CpuIntRequest( INT_REQUEST_IRQ );
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_status.hdw.t1_val =
|
mod_status.hdw.t1_val = ( mod_status.hdw.t1_val - ela_ticks ) & T1_OVF_MASK;
|
||||||
(mod_status.hdw.t1_val - ela_ticks) & T1_OVF_MASK;
|
|
||||||
|
|
||||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_TRUN)
|
if ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) {
|
||||||
{
|
ela_ticks = ( ( ela + frac_t2 ) + T2_INTERVAL / 2 ) / T2_INTERVAL;
|
||||||
ela_ticks = ((ela+frac_t2) + T2_INTERVAL/2) / T2_INTERVAL;
|
frac_t2 = ( ela + frac_t2 ) - ela_ticks * T2_INTERVAL;
|
||||||
frac_t2 = (ela+frac_t2) - ela_ticks * T2_INTERVAL;
|
|
||||||
|
|
||||||
if(ela_ticks > mod_status.hdw.t2_val)
|
if ( ela_ticks > mod_status.hdw.t2_val ) {
|
||||||
{
|
debug1( DEBUG_C_TIMERS, CPU_I_TIMER2_EX, mod_status.hdw.t2_ctrl );
|
||||||
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)
|
if ( mod_status.hdw.t2_ctrl & T2_CTRL_WAKE )
|
||||||
CpuWake();
|
CpuWake();
|
||||||
|
|
||||||
if(mod_status.hdw.t2_ctrl & T2_CTRL_INT)
|
if ( mod_status.hdw.t2_ctrl & T2_CTRL_INT )
|
||||||
CpuIntRequest(INT_REQUEST_IRQ);
|
CpuIntRequest( INT_REQUEST_IRQ );
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_status.hdw.t2_val =
|
mod_status.hdw.t2_val = ( mod_status.hdw.t2_val - ela_ticks ) & T2_OVF_MASK;
|
||||||
(mod_status.hdw.t2_val - ela_ticks) & T2_OVF_MASK;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debug3(DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (after SHUTDN)",
|
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (after SHUTDN)", mod_status.hdw.t1_ctrl, mod_status.hdw.t1_val );
|
||||||
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, "T2 (after SHUTDN)",
|
|
||||||
mod_status.hdw.t2_ctrl, mod_status.hdw.t2_val);
|
|
||||||
|
|
||||||
act = CHF_CONTINUE;
|
act = CHF_CONTINUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case CPU_I_EMULATOR_INT:
|
case CPU_I_EMULATOR_INT:
|
||||||
/* Emulator interrupt; unwind */
|
/* Emulator interrupt; unwind */
|
||||||
act = CHF_UNWIND;
|
act = CHF_UNWIND;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Condition Code not handled; resignal */
|
/* Condition Code not handled; resignal */
|
||||||
act = CHF_RESIGNAL;
|
act = CHF_RESIGNAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
/* Condition from other modules; resignal */
|
/* Condition from other modules; resignal */
|
||||||
act = CHF_RESIGNAL;
|
act = CHF_RESIGNAL;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Other states; resignal the condition */
|
/* Other states; resignal the condition */
|
||||||
act = CHF_RESIGNAL;
|
act = CHF_RESIGNAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return act;
|
return act;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : Emulator
|
.title : Emulator
|
||||||
|
@ -547,43 +516,40 @@ static ChfAction EmulatorLoopHandler(
|
||||||
a Chf Condition that triggers an unwind operation.
|
a Chf Condition that triggers an unwind operation.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Emulator();
|
Emulator();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
CPU_I_CALLED
|
CPU_I_CALLED
|
||||||
CPU_I_TIMER1_EX
|
CPU_I_TIMER1_EX
|
||||||
CPU_I_TIMER2_EX
|
CPU_I_TIMER2_EX
|
||||||
Other conditions signalled by lower level modules
|
Other conditions signalled by lower level modules
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 17-Feb-1998, creation
|
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 */
|
/* Setup unwind_context */
|
||||||
if(setjmp(unwind_context) == 0)
|
if ( setjmp( unwind_context ) == 0 ) {
|
||||||
{
|
/* Push condition handler, with NULL context */
|
||||||
/* Push condition handler, with NULL context */
|
ChfPushHandler( EmulatorLoopHandler, &unwind_context, ( ChfPointer )NULL );
|
||||||
ChfPushHandler(EmulatorLoopHandler, &unwind_context, (ChfPointer)NULL);
|
|
||||||
|
|
||||||
/* Activate emulator loop */
|
/* Activate emulator loop */
|
||||||
EmulatorLoop();
|
EmulatorLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Unwinding after an emulator interrupt */
|
||||||
/* Unwinding after an emulator interrupt */
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : EmulatorIntRequest
|
.title : EmulatorIntRequest
|
||||||
|
@ -595,22 +561,18 @@ void Emulator(void)
|
||||||
return to the caller.
|
return to the caller.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
EmulatorIntRequest();
|
EmulatorIntRequest();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
*
|
*
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 18-Feb-1998, creation
|
1.1, 18-Feb-1998, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void EmulatorIntRequest(void)
|
void EmulatorIntRequest( void ) { emulator_int_req = 1; }
|
||||||
{
|
|
||||||
emulator_int_req = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
|
@ -623,14 +585,14 @@ void EmulatorIntRequest(void)
|
||||||
subsystems, too.
|
subsystems, too.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
EmulatorInit();
|
EmulatorInit();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
* Status codes signaled by CpuInit() and CpuReset()
|
* Status codes signaled by CpuInit() and CpuReset()
|
||||||
* Status codes signaled by ModInit() and ModReset()
|
* Status codes signaled by ModInit() and ModReset()
|
||||||
.notes :
|
.notes :
|
||||||
2.1, 8-Sep-2000, creation
|
2.1, 8-Sep-2000, creation
|
||||||
2.4, 12-Sep-2000, update
|
2.4, 12-Sep-2000, update
|
||||||
|
@ -642,24 +604,22 @@ void EmulatorIntRequest(void)
|
||||||
args.hw option.
|
args.hw option.
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void EmulatorInit(void)
|
void EmulatorInit( void )
|
||||||
{
|
{
|
||||||
/* Select a module description table */
|
/* Select a module description table */
|
||||||
ModSelectDescription(args.hw);
|
ModSelectDescription( args.hw );
|
||||||
|
|
||||||
/* Initialize cpu and modules subsystems */
|
/* Initialize cpu and modules subsystems */
|
||||||
CpuInit();
|
CpuInit();
|
||||||
ModInit();
|
ModInit();
|
||||||
|
|
||||||
/* Reset if appropriate */
|
/* Reset if appropriate */
|
||||||
if(args.reset)
|
if ( args.reset ) {
|
||||||
{
|
CpuReset();
|
||||||
CpuReset();
|
ModReset();
|
||||||
ModReset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : EmulatorExit
|
.title : EmulatorExit
|
||||||
|
@ -672,30 +632,29 @@ void EmulatorInit(void)
|
||||||
returns to the caller unless an unrecoverable error occurs.
|
returns to the caller unless an unrecoverable error occurs.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
EmulatorExit(opt);
|
EmulatorExit(opt);
|
||||||
.input :
|
.input :
|
||||||
enum ExitOption opt, emulator exit option
|
enum ExitOption opt, emulator exit option
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
* Status codes signaled by CpuSave() and ModSave()
|
* Status codes signaled by CpuSave() and ModSave()
|
||||||
.notes :
|
.notes :
|
||||||
2.1, 8-Sep-2000, creation
|
2.1, 8-Sep-2000, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void EmulatorExit(enum ExitOption opt)
|
void EmulatorExit( enum ExitOption opt )
|
||||||
{
|
{
|
||||||
switch(opt)
|
switch ( opt ) {
|
||||||
{
|
|
||||||
|
|
||||||
case SAVE_AND_EXIT:
|
case SAVE_AND_EXIT:
|
||||||
/* Save state of cpu and modules subsystems */
|
/* Save state of cpu and modules subsystems */
|
||||||
ModSave();
|
ModSave();
|
||||||
CpuSave();
|
CpuSave();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Default behavior; do nothing */
|
/* Default behavior; do nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
390
src/flash49.c
390
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"
|
#include "args.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID FLASH_CHF_MODULE_ID
|
#define CHF_MODULE_ID FLASH_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Private Macro/Data type definitions
|
Private Macro/Data type definitions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define BLOCK_SIZE 0x10000
|
#define BLOCK_SIZE 0x10000
|
||||||
#define BLOCK_BASE_MASK 0xFFFF
|
#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 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 */
|
/* Flash cycle types */
|
||||||
enum FlashCycle
|
enum FlashCycle {
|
||||||
{
|
|
||||||
FLASH_CYCLE_READ = 0,
|
FLASH_CYCLE_READ = 0,
|
||||||
FLASH_CYCLE_WRITE,
|
FLASH_CYCLE_WRITE,
|
||||||
|
|
||||||
FLASH_CYCLE_N /* Total # of cycle types */
|
FLASH_CYCLE_N /* Total # of cycle types */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* State transition function */
|
/* State transition function */
|
||||||
typedef int (*FlashF)
|
typedef int ( *FlashF )( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data );
|
||||||
(enum FlashState *state, enum FlashCycle cycle,
|
|
||||||
XAddress address, int data);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Private state variables
|
Private state variables
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* External storage */
|
/* 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 r_buffer; /* Nibble buffer during read */
|
||||||
static int w_buffer; /* Nibble buffer during write */
|
static int w_buffer; /* Nibble buffer during write */
|
||||||
static enum FlashState fsm_state; /* FSM state */
|
static enum FlashState fsm_state; /* FSM state */
|
||||||
|
|
||||||
/* Write buffer */
|
/* Write buffer */
|
||||||
#define WB_COUNT_MASK 0x1F
|
#define WB_COUNT_MASK 0x1F
|
||||||
#define WB_SIZE 0x20
|
#define WB_SIZE 0x20
|
||||||
static int wb_count; /* Counter for Write to Buffer */
|
static int wb_count; /* Counter for Write to Buffer */
|
||||||
static int wb_cdown; /* Count down */
|
static int wb_cdown; /* Count down */
|
||||||
static XAddress wb_start; /* Start address for Write to Buffer */
|
static XAddress wb_start; /* Start address for Write to Buffer */
|
||||||
static int wb[WB_SIZE]; /* Write buffer */
|
static int wb[ WB_SIZE ]; /* Write buffer */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
State transition private functions
|
State transition private functions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* This function is called by default for unhandled state transitions */
|
/* This function is called by default for unhandled state transitions */
|
||||||
static int BadCommand(enum FlashState *state, enum FlashCycle cycle,
|
static int BadCommand( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||||
XAddress address, int data)
|
|
||||||
{
|
{
|
||||||
/* Unknown command: signal and reset state to FLASH_ST_READ_ARRAY */
|
/* Unknown command: signal and reset state to FLASH_ST_READ_ARRAY */
|
||||||
ChfCondition FLASH_W_BAD_CMD, CHF_WARNING,
|
ChfCondition FLASH_W_BAD_CMD, CHF_WARNING, *state, cycle, address, data ChfEnd;
|
||||||
*state, cycle, address, data
|
|
||||||
ChfEnd;
|
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
*state = FLASH_ST_READ_ARRAY;
|
*state = FLASH_ST_READ_ARRAY;
|
||||||
return 0; /* Dummy result */
|
return 0; /* Dummy result */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function is called to read the Flash Rom array */
|
/* This function is called to read the Flash Rom array */
|
||||||
static int ReadArray(enum FlashState *state, enum FlashCycle cycle,
|
static int ReadArray( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||||
XAddress address, int data)
|
|
||||||
{
|
{
|
||||||
/* Read a byte from the array; no state transitions */
|
/* Read a byte from the array; no state transitions */
|
||||||
return
|
return mod_status_49->flash[ NibbleAddress( address ) ] | ShiftHigh( mod_status_49->flash[ NibbleAddress( address ) + 1 ] );
|
||||||
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 */
|
/* This function is called to parse the first byte of any command */
|
||||||
static int ParseCommand(enum FlashState *state, enum FlashCycle cycle,
|
static int ParseCommand( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||||
XAddress address, int data)
|
|
||||||
{
|
{
|
||||||
switch(data)
|
switch ( data ) {
|
||||||
{
|
case FLASH_CMD_READ_ARRAY:
|
||||||
case FLASH_CMD_READ_ARRAY:
|
/* Transition to FLASH_ST_READ_ARRAY state */
|
||||||
/* Transition to FLASH_ST_READ_ARRAY state */
|
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Array" );
|
||||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Array");
|
*state = FLASH_ST_READ_ARRAY;
|
||||||
*state = FLASH_ST_READ_ARRAY;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case FLASH_CMD_CLR_SR:
|
case FLASH_CMD_CLR_SR:
|
||||||
/* Clear status register; section 4.5 on Data Sheet.
|
/* Clear status register; section 4.5 on Data Sheet.
|
||||||
The current implementation does nothing, because
|
The current implementation does nothing, because
|
||||||
the value of the status register is fixed. No state transitions.
|
the value of the status register is fixed. No state transitions.
|
||||||
*/
|
*/
|
||||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Clear Status");
|
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Clear Status" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLASH_CMD_WRITE_BUFFER:
|
case FLASH_CMD_WRITE_BUFFER:
|
||||||
/* Write to Buffer; section 4.8 on Data Sheet.
|
/* Write to Buffer; section 4.8 on Data Sheet.
|
||||||
Transition to FLASH_ST_READ_XSR state.
|
Transition to FLASH_ST_READ_XSR state.
|
||||||
*/
|
*/
|
||||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (start)");
|
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (start)" );
|
||||||
*state = FLASH_ST_READ_XSR;
|
*state = FLASH_ST_READ_XSR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLASH_CMD_READ_SR:
|
case FLASH_CMD_READ_SR:
|
||||||
/* Read Status; section 4.4 on Data Sheet.
|
/* Read Status; section 4.4 on Data Sheet.
|
||||||
Transition to FLASH_ST_READ_SR state.
|
Transition to FLASH_ST_READ_SR state.
|
||||||
*/
|
*/
|
||||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Status");
|
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Status" );
|
||||||
*state = FLASH_ST_READ_SR;
|
*state = FLASH_ST_READ_SR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLASH_CMD_BL_ERASE:
|
case FLASH_CMD_BL_ERASE:
|
||||||
/* Block Erase; section 4.6 on Data Sheet.
|
/* Block Erase; section 4.6 on Data Sheet.
|
||||||
Transition to FLASH_ST_BL_ERASE state.
|
Transition to FLASH_ST_BL_ERASE state.
|
||||||
Consistency of block addresses is not checked.
|
Consistency of block addresses is not checked.
|
||||||
*/
|
*/
|
||||||
debug1(DEBUG_C_FLASH, FLASH_I_FSM_OP, "Erase Block (start)");
|
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Erase Block (start)" );
|
||||||
*state = FLASH_ST_BL_ERASE;
|
*state = FLASH_ST_BL_ERASE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Unknown command; signal, ignore, keep current state. */
|
/* Unknown command; signal, ignore, keep current state. */
|
||||||
ChfCondition FLASH_W_BAD_CMD, CHF_WARNING,
|
ChfCondition FLASH_W_BAD_CMD, CHF_WARNING, *state, cycle, address, data ChfEnd;
|
||||||
*state, cycle, address, data
|
ChfSignal();
|
||||||
ChfEnd;
|
break;
|
||||||
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 */
|
/* This function returns to the caller the value of XSR */
|
||||||
static int ReadXSR(enum FlashState *state, enum FlashCycle cycle,
|
static int ReadXSR( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||||
XAddress address, int data)
|
|
||||||
{
|
{
|
||||||
/* Return XSR status; a buffer is always available in the current
|
/* Return XSR status; a buffer is always available in the current
|
||||||
emulation scheme. Keep current state.
|
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;
|
return FLASH_XSR_WBS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function returns to the caller the value of SR */
|
/* This function returns to the caller the value of SR */
|
||||||
static int ReadSR(enum FlashState *state, enum FlashCycle cycle,
|
static int ReadSR( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||||
XAddress address, int data)
|
|
||||||
{
|
{
|
||||||
/* Return SR status; the WSM executes in zero time in the current
|
/* Return SR status; the WSM executes in zero time in the current
|
||||||
emulation scheme. Keep current state.
|
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;
|
return FLASH_SR_WSMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function is called to store the WRITE_BUFFER byte count;
|
/* This function is called to store the WRITE_BUFFER byte count;
|
||||||
both wb_count and wb_cdown are set; StoreData() decrements the
|
both wb_count and wb_cdown are set; StoreData() decrements the
|
||||||
latter, WriteConfirm() uses the former to determine how many bytes
|
latter, WriteConfirm() uses the former to determine how many bytes
|
||||||
must write to the Flash array.
|
must write to the Flash array.
|
||||||
*/
|
*/
|
||||||
static int StoreCount(enum FlashState *state, enum FlashCycle cycle,
|
static int StoreCount( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||||
XAddress address, int data)
|
|
||||||
{
|
{
|
||||||
/* Store WRITE_BUFFER count; next state is FLASH_ST_WRITE_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;
|
wb_count = wb_cdown = data & WB_COUNT_MASK;
|
||||||
|
|
||||||
*state = FLASH_ST_WRITE_DATA_1;
|
*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.
|
/* 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 first write cycle also sets the buffer's base address (wb_start).
|
||||||
The function transitions to state FLASH_ST_WRITE_CONFIRM when all
|
The function transitions to state FLASH_ST_WRITE_CONFIRM when all
|
||||||
bytes have been stored.
|
bytes have been stored.
|
||||||
*/
|
*/
|
||||||
static int StoreData(enum FlashState *state, enum FlashCycle cycle,
|
static int StoreData( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||||
XAddress address, int data)
|
|
||||||
{
|
{
|
||||||
int index;
|
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
|
/* Store WRITE_BUFFER data; the first write also stores the
|
||||||
buffer starting address.
|
buffer starting address.
|
||||||
*/
|
*/
|
||||||
switch(*state)
|
switch ( *state ) {
|
||||||
{
|
|
||||||
|
|
||||||
case FLASH_ST_WRITE_DATA_1:
|
case FLASH_ST_WRITE_DATA_1:
|
||||||
wb_start = address;
|
wb_start = address;
|
||||||
wb[0] = data;
|
wb[ 0 ] = data;
|
||||||
*state = FLASH_ST_WRITE_DATA_N;
|
*state = FLASH_ST_WRITE_DATA_N;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLASH_ST_WRITE_DATA_N:
|
case FLASH_ST_WRITE_DATA_N:
|
||||||
index = address - wb_start;
|
index = address - wb_start;
|
||||||
if(index < 0 || index >= WB_SIZE)
|
if ( index < 0 || index >= WB_SIZE ) {
|
||||||
{
|
ChfCondition FLASH_W_BAD_ADDRESS, CHF_WARNING, *state, cycle, address, data ChfEnd;
|
||||||
ChfCondition FLASH_W_BAD_ADDRESS, CHF_WARNING,
|
ChfSignal();
|
||||||
*state, cycle, address, data
|
} else
|
||||||
ChfEnd;
|
wb[ index ] = data;
|
||||||
ChfSignal();
|
break;
|
||||||
}
|
|
||||||
else
|
|
||||||
wb[index] = data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*state = FLASH_ST_READ_ARRAY;
|
*state = FLASH_ST_READ_ARRAY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(--wb_cdown < 0)
|
if ( --wb_cdown < 0 )
|
||||||
*state = FLASH_ST_WRITE_CONFIRM;
|
*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
|
/* This function expects a Write to Buffer confirmation command
|
||||||
(FLASH_CMD_WRITE_BUFFER_2); if it is received, the write buffer
|
(FLASH_CMD_WRITE_BUFFER_2); if it is received, the write buffer
|
||||||
is copied into the Flash Rom array, otherwise the write cycle is
|
is copied into the Flash Rom array, otherwise the write cycle is
|
||||||
aborted. In both cases, the new state is FLASH_ST_READ_ARRAY.
|
aborted. In both cases, the new state is FLASH_ST_READ_ARRAY.
|
||||||
*/
|
*/
|
||||||
static int WriteConfirm(enum FlashState *state, enum FlashCycle cycle,
|
static int WriteConfirm( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||||
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 */
|
/* Expect Write to Buffer confirmation code */
|
||||||
if(data == FLASH_CMD_WRITE_BUFFER_2)
|
if ( data == FLASH_CMD_WRITE_BUFFER_2 ) {
|
||||||
{
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Confirmation OK; write.
|
/* Confirmation OK; write.
|
||||||
Remember that wb_count is the byte count MINUS 1.
|
Remember that wb_count is the byte count MINUS 1.
|
||||||
*/
|
*/
|
||||||
for(i=0; i<=wb_count; i++)
|
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)]
|
mod_status_49->flash[ NibbleAddress( wb_start + i ) + 1 ] = HighNibble( wb[ i ] );
|
||||||
= LowNibble(wb[i]);
|
}
|
||||||
mod_status_49->flash[NibbleAddress(wb_start+i)+1]
|
|
||||||
= HighNibble(wb[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*state = FLASH_ST_READ_ARRAY;
|
*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
|
/* If the FLASH_CMD_BL_ERASE_2 command is received, this function erases
|
||||||
the block pointed by the current address; otherwise the block erase
|
the block pointed by the current address; otherwise the block erase
|
||||||
operation is aborted.
|
operation is aborted.
|
||||||
In both cases, the new state is FLASH_ST_READ_SR.
|
In both cases, the new state is FLASH_ST_READ_SR.
|
||||||
*/
|
*/
|
||||||
static int BlockErase(enum FlashState *state, enum FlashCycle cycle,
|
static int BlockErase( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||||
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 */
|
/* Expect Write to Buffer confirmation code */
|
||||||
if(data == FLASH_CMD_BL_ERASE_2)
|
if ( data == FLASH_CMD_BL_ERASE_2 ) {
|
||||||
{
|
XAddress block_base = BlockBase( address );
|
||||||
XAddress block_base = BlockBase(address);
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Confirmation OK; erase */
|
/* Confirmation OK; erase */
|
||||||
for(i=0; i<BLOCK_SIZE; i++)
|
for ( i = 0; i < BLOCK_SIZE; i++ ) {
|
||||||
{
|
mod_status_49->flash[ NibbleAddress( block_base + i ) ] = ( Nibble )0xF;
|
||||||
mod_status_49->flash[
|
mod_status_49->flash[ NibbleAddress( block_base + i ) + 1 ] = ( Nibble )0xF;
|
||||||
NibbleAddress(block_base+i)] = (Nibble)0xF;
|
}
|
||||||
mod_status_49->flash[
|
|
||||||
NibbleAddress(block_base+i)+1] = (Nibble)0xF;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*state = FLASH_ST_READ_SR;
|
*state = FLASH_ST_READ_SR;
|
||||||
return 0; /* No result */
|
return 0; /* No result */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
FSM state diagram; two-dimensional array of FlashF; each function
|
FSM state diagram; two-dimensional array of FlashF; each function
|
||||||
is invoked when the FSM is in a given state (first index), and
|
is invoked when the FSM is in a given state (first index), and
|
||||||
a particular cycle (second index) is requested.
|
a particular cycle (second index) is requested.
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static FlashF F[FLASH_ST_N][FLASH_CYCLE_N] =
|
static FlashF F[ FLASH_ST_N ][ FLASH_CYCLE_N ] = {
|
||||||
{
|
{ReadArray, ParseCommand}, /* FLASH_ST_READ_ARRAY */
|
||||||
{ ReadArray, ParseCommand }, /* FLASH_ST_READ_ARRAY */
|
{ReadSR, ParseCommand}, /* FLASH_ST_READ_SR */
|
||||||
{ ReadSR, ParseCommand }, /* FLASH_ST_READ_SR */
|
{ReadXSR, StoreCount }, /* FLASH_ST_READ_XSR */
|
||||||
{ ReadXSR, StoreCount }, /* FLASH_ST_READ_XSR */
|
{BadCommand, StoreData }, /* FLASH_ST_WRITE_DATA_1 */
|
||||||
{ BadCommand, StoreData }, /* FLASH_ST_WRITE_DATA_1 */
|
{BadCommand, StoreData }, /* FLASH_ST_WRITE_DATA_N */
|
||||||
{ BadCommand, StoreData }, /* FLASH_ST_WRITE_DATA_N */
|
{BadCommand, WriteConfirm}, /* FLASH_ST_WRITE_CONFIRM */
|
||||||
{ BadCommand, WriteConfirm }, /* FLASH_ST_WRITE_CONFIRM */
|
{BadCommand, BlockErase } /* FLASH_ST_BL_ERASE */
|
||||||
{ BadCommand, BlockErase } /* FLASH_ST_BL_ERASE */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Other private functions
|
Other private functions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
@ -415,25 +362,23 @@ static FlashF F[FLASH_ST_N][FLASH_CYCLE_N] =
|
||||||
with 'address' and 'data' as arguments. Returns the
|
with 'address' and 'data' as arguments. Returns the
|
||||||
result of the FSM, if any.
|
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;
|
int result;
|
||||||
|
|
||||||
debug2(DEBUG_C_FLASH, FLASH_I_FSM, fsm_state, cycle);
|
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_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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : FlashRead49
|
.title : FlashRead49
|
||||||
|
@ -447,41 +392,38 @@ static int FSM(enum FlashCycle cycle, XAddress address, int data)
|
||||||
addresses.
|
addresses.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
n = FlashRead49(address);
|
n = FlashRead49(address);
|
||||||
.input :
|
.input :
|
||||||
XAddress address
|
XAddress address
|
||||||
.output :
|
.output :
|
||||||
Nibble n
|
Nibble n
|
||||||
.status_codes :
|
.status_codes :
|
||||||
FLASH_I_READ
|
FLASH_I_READ
|
||||||
FLASH_I_FSM_OP
|
FLASH_I_FSM_OP
|
||||||
FLASH_W_BAD_CMD
|
FLASH_W_BAD_CMD
|
||||||
.notes :
|
.notes :
|
||||||
3.3, 25-Sep-2000, creation
|
3.3, 25-Sep-2000, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
Nibble FlashRead49(XAddress address)
|
Nibble FlashRead49( XAddress address )
|
||||||
{
|
{
|
||||||
Nibble result;
|
Nibble result;
|
||||||
|
|
||||||
if(IsOdd(address))
|
if ( IsOdd( address ) )
|
||||||
/* Odd address, return buffered data from previous read */
|
/* Odd address, return buffered data from previous read */
|
||||||
result = HighNibble(r_buffer);
|
result = HighNibble( r_buffer );
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Even address, invoke FSM */
|
||||||
/* Even address, invoke FSM */
|
r_buffer = FSM( FLASH_CYCLE_READ, ByteAddress( address ), 0 );
|
||||||
r_buffer = FSM(FLASH_CYCLE_READ, ByteAddress(address), 0);
|
result = LowNibble( r_buffer );
|
||||||
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : FlashWrite49
|
.title : FlashWrite49
|
||||||
|
@ -494,32 +436,30 @@ Nibble FlashRead49(XAddress address)
|
||||||
addresses.
|
addresses.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
FlashWrite49(address, datum);
|
FlashWrite49(address, datum);
|
||||||
.input :
|
.input :
|
||||||
XAddress address
|
XAddress address
|
||||||
Nibble datum
|
Nibble datum
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
FLASH_I_WRITE
|
FLASH_I_WRITE
|
||||||
FLASH_I_FSM_OP
|
FLASH_I_FSM_OP
|
||||||
FLASH_W_BAD_CMD
|
FLASH_W_BAD_CMD
|
||||||
FLASH_W_BAD_ADDRESS
|
FLASH_W_BAD_ADDRESS
|
||||||
.notes :
|
.notes :
|
||||||
3.3, 25-Sep-2000, creation
|
3.3, 25-Sep-2000, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void FlashWrite49(XAddress address, Nibble datum)
|
void FlashWrite49( XAddress address, Nibble datum )
|
||||||
{
|
{
|
||||||
debug2(DEBUG_C_TRACE|DEBUG_C_FLASH, FLASH_I_WRITE, address, datum);
|
debug2( DEBUG_C_TRACE | DEBUG_C_FLASH, FLASH_I_WRITE, address, datum );
|
||||||
|
|
||||||
if(IsOdd(address))
|
if ( IsOdd( address ) )
|
||||||
/* Odd address, invoke FSM; ignore result */
|
/* Odd address, invoke FSM; ignore result */
|
||||||
FSM(FLASH_CYCLE_WRITE, ByteAddress(address),
|
FSM( FLASH_CYCLE_WRITE, ByteAddress( address ), w_buffer | ShiftHigh( datum ) );
|
||||||
w_buffer|ShiftHigh(datum));
|
|
||||||
|
|
||||||
else
|
else
|
||||||
/* Even address, buffer datum */
|
/* Even address, buffer datum */
|
||||||
w_buffer = datum;
|
w_buffer = datum;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
115
src/flash49.h
115
src/flash49.h
|
@ -31,7 +31,6 @@
|
||||||
|
|
||||||
/* +-+ */
|
/* +-+ */
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.identifier : $Id: flash49.h,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
.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.
|
/* Command Set Definitions, Table 3 on Data Sheet.
|
||||||
Both BCS and SCS commands are listed here; commands marked with
|
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.
|
The last fixed byte of multibyte commands has a '_2' suffix.
|
||||||
*/
|
*/
|
||||||
#define FLASH_CMD_READ_ARRAY 0xFF /* BCS */
|
#define FLASH_CMD_READ_ARRAY 0xFF /* BCS */
|
||||||
#define FLASH_CMD_READ_ID 0x90 /* BCS (*) */
|
#define FLASH_CMD_READ_ID 0x90 /* BCS (*) */
|
||||||
#define FLASH_CMD_READ_QUERY 0x98 /* SCS (*) */
|
#define FLASH_CMD_READ_QUERY 0x98 /* SCS (*) */
|
||||||
#define FLASH_CMD_READ_SR 0x70 /* BCS */
|
#define FLASH_CMD_READ_SR 0x70 /* BCS */
|
||||||
#define FLASH_CMD_CLR_SR 0x50 /* BCS */
|
#define FLASH_CMD_CLR_SR 0x50 /* BCS */
|
||||||
#define FLASH_CMD_WRITE_BUFFER 0xE8 /* SCS */
|
#define FLASH_CMD_WRITE_BUFFER 0xE8 /* SCS */
|
||||||
# define FLASH_CMD_WRITE_BUFFER_2 0xD0
|
#define FLASH_CMD_WRITE_BUFFER_2 0xD0
|
||||||
#define FLASH_CMD_BW_PGM 0x40 /* BCS (*) */
|
#define FLASH_CMD_BW_PGM 0x40 /* BCS (*) */
|
||||||
#define FLASH_CMD_BW_PGM_ALT 0x10 /* BCS, alternate (*) */
|
#define FLASH_CMD_BW_PGM_ALT 0x10 /* BCS, alternate (*) */
|
||||||
#define FLASH_CMD_BL_ERASE 0x20 /* BCS */
|
#define FLASH_CMD_BL_ERASE 0x20 /* BCS */
|
||||||
# define FLASH_CMD_BL_ERASE_2 0xD0
|
#define FLASH_CMD_BL_ERASE_2 0xD0
|
||||||
#define FLASH_CMD_SUSPEND 0xB0 /* BCS (*) */
|
#define FLASH_CMD_SUSPEND 0xB0 /* BCS (*) */
|
||||||
#define FLASH_CMD_RESUME 0xD0 /* BCS (*) */
|
#define FLASH_CMD_RESUME 0xD0 /* BCS (*) */
|
||||||
#define FLASH_CMD_STS_CONFIG 0xB8 /* SCS (*) */
|
#define FLASH_CMD_STS_CONFIG 0xB8 /* SCS (*) */
|
||||||
#define FLASH_CMD_BL_LB 0x60 /* SCS (*) */
|
#define FLASH_CMD_BL_LB 0x60 /* SCS (*) */
|
||||||
# define FLASH_CMD_BL_LB_SET 0x01
|
#define FLASH_CMD_BL_LB_SET 0x01
|
||||||
# define FLASH_CMD_BL_LB_CLR 0xD0
|
#define FLASH_CMD_BL_LB_CLR 0xD0
|
||||||
#define FLASH_CMD_CHIP_ERASE 0x30 /* SCS (*) */
|
#define FLASH_CMD_CHIP_ERASE 0x30 /* SCS (*) */
|
||||||
# define FLASH_CMD_CHIP_ERASE_2 0xD0
|
#define FLASH_CMD_CHIP_ERASE_2 0xD0
|
||||||
|
|
||||||
|
|
||||||
/* Status Register bit masks, Table 15 on Data Sheet
|
/* Status Register bit masks, Table 15 on Data Sheet
|
||||||
*/
|
*/
|
||||||
#define FLASH_SR_WSMS 0x80 /* WSM state, 0=busy, 1=ready */
|
#define FLASH_SR_WSMS 0x80 /* WSM state, 0=busy, 1=ready */
|
||||||
#define FLASH_SR_ESS 0x40 /* Erase suspend, 1=suspended */
|
#define FLASH_SR_ESS 0x40 /* Erase suspend, 1=suspended */
|
||||||
#define FLASH_SR_ECLBS 0x20 /* 1=Error during erasure */
|
#define FLASH_SR_ECLBS 0x20 /* 1=Error during erasure */
|
||||||
#define FLASH_SR_BWSLBS 0x10 /* 1=Error during program */
|
#define FLASH_SR_BWSLBS 0x10 /* 1=Error during program */
|
||||||
#define FLASH_SR_VPPS 0x08 /* 1=Vpp error */
|
#define FLASH_SR_VPPS 0x08 /* 1=Vpp error */
|
||||||
#define FLASH_SR_BWSS 0x04 /* Program suspend, 1=suspended */
|
#define FLASH_SR_BWSS 0x04 /* Program suspend, 1=suspended */
|
||||||
#define FLASH_SR_DPS 0x02 /* 1=Lock encountered */
|
#define FLASH_SR_DPS 0x02 /* 1=Lock encountered */
|
||||||
|
|
||||||
|
|
||||||
/* Extended Status Register bit masks, Table 16 on Data Sheet
|
/* Extended Status Register bit masks, Table 16 on Data Sheet
|
||||||
*/
|
*/
|
||||||
#define FLASH_XSR_WBS 0x80 /* Write buffer status 1=available */
|
#define FLASH_XSR_WBS 0x80 /* Write buffer status 1=available */
|
||||||
|
|
||||||
|
|
||||||
/* State of the Flash FSM, derived from command descriptions on
|
/* State of the Flash FSM, derived from command descriptions on
|
||||||
pages 16...28 and from flowcharts on Figure 6...12 of Data Sheet
|
pages 16...28 and from flowcharts on Figure 6...12 of Data Sheet
|
||||||
*/
|
*/
|
||||||
enum FlashState
|
enum FlashState {
|
||||||
{
|
FLASH_ST_READ_ARRAY = 0, /* Read Array after CMD_READ_ARRAY */
|
||||||
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_SR, /* Read Status Reg. after CMD_READ_SR */
|
FLASH_ST_READ_XSR, /* Read XSR after CMD_WRITE_BUFFER */
|
||||||
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_1, /* Write data after ST_WRITE_COUNT */
|
FLASH_ST_WRITE_DATA_N, /* Write data after first write */
|
||||||
FLASH_ST_WRITE_DATA_N, /* Write data after first write */
|
FLASH_ST_WRITE_CONFIRM, /* Write confirmation after (ST_WRITE_DATA)* */
|
||||||
FLASH_ST_WRITE_CONFIRM, /* Write confirmation after (ST_WRITE_DATA)* */
|
FLASH_ST_BL_ERASE, /* Block erase started */
|
||||||
FLASH_ST_BL_ERASE, /* Block erase started */
|
FLASH_ST_N /* Total # of FSM states */
|
||||||
FLASH_ST_N /* Total # of FSM states */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Chf condition codes
|
Chf condition codes
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define FLASH_I_READ 101 /* Read from address %x: %d */
|
#define FLASH_I_READ 101 /* Read from address %x: %d */
|
||||||
#define FLASH_I_WRITE 102 /* Write address %x, datum %x */
|
#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 103 /* FSM from state %d, cycle %d */
|
||||||
#define FLASH_I_FSM_AD 104 /* FSM address %x, data %x */
|
#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_RESULT 105 /* FSM next state %d, result %x */
|
||||||
#define FLASH_I_FSM_OP 106 /* FSM operation %s */
|
#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_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_W_BAD_ADDRESS 202 /* Bad addr st%d, cycle%d, a%x, d%d */
|
||||||
#define FLASH_E_xxx 301
|
#define FLASH_E_xxx 301
|
||||||
#define FLASH_F_xxx 401
|
#define FLASH_F_xxx 401
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Function prototypes
|
Function prototypes
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Read/Write operations, nibble-by-nibble */
|
/* Read/Write operations, nibble-by-nibble */
|
||||||
Nibble FlashRead49(XAddress address);
|
Nibble FlashRead49( XAddress address );
|
||||||
void FlashWrite49(XAddress address, Nibble datum);
|
void FlashWrite49( XAddress address, Nibble datum );
|
||||||
|
|
604
src/hdw.c
604
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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h> /* 3.1: memset() */
|
#include <string.h> /* 3.1: memset() */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "config.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 "cpu.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
#include "disk_io.h"
|
#include "disk_io.h"
|
||||||
#include "serial.h" /* 2.5: Serial port emulation module */
|
#include "serial.h" /* 2.5: Serial port emulation module */
|
||||||
#include "x_func.h" /* 3.13: Extended emulator functions */
|
#include "x_func.h" /* 3.13: Extended emulator functions */
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
static const int addr_mask[] = { 0x0000F, 0x000F0, 0x00F00, 0x0F000, 0xF0000 };
|
static const int addr_mask[] = { 0x0000F, 0x000F0, 0x00F00, 0x0F000, 0xF0000 };
|
||||||
|
|
||||||
static const int32 int32_mask[] =
|
static const int32 int32_mask[] = { 0x0000000F, 0x000000F0, 0x00000F00, 0x0000F000, 0x000F0000, 0x00F00000, 0x0F000000, 0xF0000000 };
|
||||||
{ 0x0000000F, 0x000000F0, 0x00000F00, 0x0000F000,
|
|
||||||
0x000F0000, 0x00F00000, 0x0F000000, 0xF0000000 };
|
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
|
@ -141,35 +137,32 @@ static const int32 int32_mask[] =
|
||||||
peripheral devices associated to it from disk.
|
peripheral devices associated to it from disk.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
HdwInit();
|
HdwInit();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_W_HDW_INIT
|
MOD_W_HDW_INIT
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, bug fix:
|
2.4, 11-Sep-2000, bug fix:
|
||||||
memset() invocation was improper, and could lead to memory corruption
|
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),
|
if ( ReadStructFromFile( args.hdw_file_name, sizeof( mod_status.hdw ), &mod_status.hdw ) ) {
|
||||||
&mod_status.hdw))
|
ChfCondition MOD_W_HDW_INIT, CHF_WARNING ChfEnd;
|
||||||
{
|
ChfSignal();
|
||||||
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
|
.title : HdwSave
|
||||||
|
@ -180,31 +173,28 @@ void HdwInit(void)
|
||||||
to the Hdw module to disk.
|
to the Hdw module to disk.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
HdwSave();
|
HdwSave();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_HDW_SAVE
|
MOD_E_HDW_SAVE
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 11-Feb-1998, creation
|
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),
|
if ( WriteStructToFile( &mod_status.hdw, sizeof( mod_status.hdw ), args.hdw_file_name ) ) {
|
||||||
args.hdw_file_name))
|
ChfCondition MOD_E_HDW_SAVE, CHF_ERROR ChfEnd;
|
||||||
{
|
ChfSignal();
|
||||||
ChfCondition MOD_E_HDW_SAVE, CHF_ERROR ChfEnd;
|
}
|
||||||
ChfSignal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : HdwRead
|
.title : HdwRead
|
||||||
|
@ -214,14 +204,14 @@ void HdwSave(void)
|
||||||
This function reads a nibble from the Hdw module.
|
This function reads a nibble from the Hdw module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = HdwRead(rel_address);
|
d = HdwRead(rel_address);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, relative address
|
Address rel_address, relative address
|
||||||
.output :
|
.output :
|
||||||
Nibble d, data
|
Nibble d, data
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_W_HDW_READ
|
MOD_W_HDW_READ
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, update
|
2.4, 11-Sep-2000, update
|
||||||
|
@ -232,130 +222,127 @@ void HdwSave(void)
|
||||||
- added support for serial port emulation
|
- 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.
|
/* 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[],
|
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
|
simply put a break in the case, otherwise code any special action for
|
||||||
the register and end the case with a return.
|
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.
|
|
||||||
*/
|
*/
|
||||||
case 0x14:
|
switch ( rel_address ) {
|
||||||
return (mod_status.hdw.serial_rbr = Serial_RBR_Read()) & 0x0F;
|
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:
|
case 0x04: /* CRC register */
|
||||||
return (mod_status.hdw.serial_rbr >> 4) & 0x0F;
|
case 0x05:
|
||||||
|
case 0x06:
|
||||||
|
case 0x07:
|
||||||
|
return ( Nibble )( ( mod_status.hdw.crc >> ( ( rel_address - 0x04 ) * 4 ) ) & 0x0F );
|
||||||
|
|
||||||
case 0x0E: /* Card interface */
|
case 0x08: /* Power status */
|
||||||
break;
|
/* No power status related interrupt have occoured */
|
||||||
|
return ( Nibble )0;
|
||||||
|
|
||||||
case 0x0F: /* Card interface */
|
case 0x09: /* Power control */
|
||||||
/* 2.4: Return current card status */
|
break;
|
||||||
return mod_status.hdw.card_status;
|
|
||||||
|
|
||||||
case 0x18: /* Service request */
|
case 0x0D: /* Serial port baud-rate register */
|
||||||
case 0x19:
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x1A: /* IR registers */
|
case 0x10: /* Serial port interrupt and I/O control register */
|
||||||
case 0x1C:
|
return Serial_IOC_Read();
|
||||||
case 0x1D:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x1B: /* Base nibble offset */
|
case 0x11: /* Serial port receiver control/status register */
|
||||||
break;
|
return Serial_RCS_Read();
|
||||||
|
|
||||||
case 0x1E: /* Scratch pad */
|
case 0x12: /* Serial port transmitter control/status register */
|
||||||
break;
|
return Serial_TCS_Read();
|
||||||
|
|
||||||
case 0x1F: /* Base Nibble */
|
/* Serial port receiver buffer register; the actual read takes place
|
||||||
break;
|
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 */
|
case 0x15:
|
||||||
return mod_status.hdw.t1_ctrl;
|
return ( mod_status.hdw.serial_rbr >> 4 ) & 0x0F;
|
||||||
|
|
||||||
case 0x2F: /* Timer 2 Control */
|
case 0x0E: /* Card interface */
|
||||||
return mod_status.hdw.t2_ctrl;
|
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
|
#ifdef HP49_SUPPORT
|
||||||
/* 3.2: The HP49 firmware (1.19-4) reads a nibble from 0x30 */
|
/* 3.2: The HP49 firmware (1.19-4) reads a nibble from 0x30 */
|
||||||
case 0x30:
|
case 0x30:
|
||||||
case 0x31:
|
case 0x31:
|
||||||
case 0x32:
|
case 0x32:
|
||||||
case 0x33:
|
case 0x33:
|
||||||
case 0x34:
|
case 0x34:
|
||||||
return (Nibble)0x0;
|
return ( Nibble )0x0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case 0x37: /* Timer 1 value */
|
case 0x37: /* Timer 1 value */
|
||||||
return mod_status.hdw.t1_val;
|
return mod_status.hdw.t1_val;
|
||||||
|
|
||||||
case 0x38: /* Timer 2 value */
|
case 0x38: /* Timer 2 value */
|
||||||
case 0x39:
|
case 0x39:
|
||||||
case 0x3A:
|
case 0x3A:
|
||||||
case 0x3B:
|
case 0x3B:
|
||||||
case 0x3C:
|
case 0x3C:
|
||||||
case 0x3D:
|
case 0x3D:
|
||||||
case 0x3E:
|
case 0x3E:
|
||||||
case 0x3F:
|
case 0x3F:
|
||||||
return
|
return ( Nibble )( ( mod_status.hdw.t2_val >> ( ( rel_address - 0x38 ) * 4 ) ) & 0x0F );
|
||||||
(Nibble)((mod_status.hdw.t2_val >> ((rel_address-0x38)*4)) & 0x0F);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ChfCondition MOD_W_HDW_READ, CHF_WARNING, rel_address ChfEnd;
|
ChfCondition MOD_W_HDW_READ, CHF_WARNING, rel_address ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
return (Nibble)0xF;
|
return ( Nibble )0xF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read from hdw register array */
|
/* Read from hdw register array */
|
||||||
return mod_status.hdw.hdw[rel_address];
|
return mod_status.hdw.hdw[ rel_address ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : HdwWrite
|
.title : HdwWrite
|
||||||
|
@ -365,201 +352,198 @@ Nibble HdwRead(Address rel_address)
|
||||||
This function writes a nibble to the Hdw module.
|
This function writes a nibble to the Hdw module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
HdwWrite(rel_address, data);
|
HdwWrite(rel_address, data);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, relative address
|
Address rel_address, relative address
|
||||||
Nibble data, data to be written
|
Nibble data, data to be written
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_W_HDW_WRITE
|
MOD_W_HDW_WRITE
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.5, 14-Sep-2000, update
|
2.5, 14-Sep-2000, update
|
||||||
- added support for serial port emulation
|
- 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
|
/* 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
|
case performs the actions specific for that register; the code following
|
||||||
the switch, instead, simply takes care to shadow the hdw register into
|
the switch, instead, simply takes care to shadow the hdw register into
|
||||||
the mod_status.hdw.hdw[] array
|
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.
|
|
||||||
*/
|
*/
|
||||||
case 0x14:
|
switch ( rel_address ) {
|
||||||
ExtendedFunction(data);
|
case 0x00: /* LCD horizontal offset, LCD enable flag */
|
||||||
break;
|
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
|
case 0x01: /* LCD contrast, LS nibble */
|
||||||
when the MS nibble is written; serial_tbr buffers the LS nibble.
|
mod_status.hdw.lcd_contrast &= 0x10;
|
||||||
*/
|
mod_status.hdw.lcd_contrast |= ( int )data;
|
||||||
case 0x16:
|
break;
|
||||||
mod_status.hdw.serial_tbr =
|
|
||||||
(mod_status.hdw.serial_tbr & 0xF0) | (int8)data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x17:
|
case 0x02: /* LCD contrast, MS bit */
|
||||||
mod_status.hdw.serial_tbr =
|
mod_status.hdw.lcd_contrast &= 0x0F;
|
||||||
(mod_status.hdw.serial_tbr & 0x0F) | ((int8)data << 4);
|
mod_status.hdw.lcd_contrast |= ( ( ( int )data & 0x01 ) << 4 );
|
||||||
Serial_TBR_Write(mod_status.hdw.serial_tbr);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x18: /* Service request */
|
case 0x03: /* LCD test control */
|
||||||
case 0x19:
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x1A: /* IR Control Register */
|
case 0x04: /* CRC register */
|
||||||
break;
|
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 */
|
case 0x08: /* Power status and power control */
|
||||||
break;
|
case 0x09:
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x1C: /* IR Status Register */
|
case 0x0B: /* LCD annunciator control (low nibble) */
|
||||||
break;
|
mod_status.hdw.lcd_ann &= 0xF0;
|
||||||
|
mod_status.hdw.lcd_ann |= ( int )data;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x1D: /* IR Led Buffer */
|
case 0x0C: /* LCD annunciator control (high nibble) */
|
||||||
break;
|
mod_status.hdw.lcd_ann &= 0x0F;
|
||||||
|
mod_status.hdw.lcd_ann |= ( ( int )data << 4 );
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x1E: /* Scratch Pad */
|
case 0x0D: /* Serial port baud rate */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1F: /* Base Nibble */
|
case 0x0E: /* Card interface */
|
||||||
break;
|
case 0x0F:
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x20: /* LCD base address register (write only) */
|
case 0x10: /* Serial port interrupt and I/O control/status */
|
||||||
case 0x21:
|
Serial_IOC_Write( data );
|
||||||
case 0x22:
|
break;
|
||||||
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 0x11: /* Serial port receiver control/status register */
|
||||||
case 0x26:
|
Serial_RCS_Write( data );
|
||||||
case 0x27:
|
break;
|
||||||
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) */
|
case 0x12: /* Serial port transmitter control/status register */
|
||||||
mod_status.hdw.lcd_vlc &= 0x30;
|
Serial_TCS_Write( data );
|
||||||
mod_status.hdw.lcd_vlc |= (int)data;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x29: /* LCD vertical line count (higher 2 bits), others (TBD) */
|
case 0x13: /* Clear serial port receive error */
|
||||||
mod_status.hdw.lcd_vlc &= 0x0F;
|
Serial_CRER_Write( data );
|
||||||
mod_status.hdw.lcd_vlc |= (((int)data & 0x03) << 4);
|
break;
|
||||||
|
|
||||||
case 0x2E: /* Timer 1 Control */
|
/* 3.13: A write operation into the receiver buffer register
|
||||||
mod_status.hdw.t1_ctrl = data;
|
triggers an extended emulator function.
|
||||||
break;
|
*/
|
||||||
|
case 0x14:
|
||||||
|
ExtendedFunction( data );
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x2F: /* Timer 2 Control */
|
/* Serial port transmitter buffer; the actual write takes place
|
||||||
mod_status.hdw.t2_ctrl = data;
|
when the MS nibble is written; serial_tbr buffers the LS nibble.
|
||||||
break;
|
*/
|
||||||
|
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 0x17:
|
||||||
case 0x31:
|
mod_status.hdw.serial_tbr = ( mod_status.hdw.serial_tbr & 0x0F ) | ( ( int8 )data << 4 );
|
||||||
case 0x32:
|
Serial_TBR_Write( mod_status.hdw.serial_tbr );
|
||||||
case 0x33:
|
break;
|
||||||
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 */
|
case 0x18: /* Service request */
|
||||||
mod_status.hdw.t1_val = data;
|
case 0x19:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x38: /* Timer 2 value */
|
case 0x1A: /* IR Control Register */
|
||||||
case 0x39:
|
break;
|
||||||
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:
|
case 0x1B: /* Base nibble offset */
|
||||||
ChfCondition MOD_W_HDW_WRITE, CHF_WARNING, rel_address, (int)data ChfEnd;
|
break;
|
||||||
ChfSignal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save copy into hdw register array */
|
case 0x1C: /* IR Status Register */
|
||||||
mod_status.hdw.hdw[rel_address] = data;
|
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 "modules.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Module description tables
|
Module description tables
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
extern void RomInit(void);
|
extern void RomInit( void );
|
||||||
extern void HdwInit(void);
|
extern void HdwInit( void );
|
||||||
extern void RamInit(void);
|
extern void RamInit( void );
|
||||||
extern void Ce1Init(void);
|
extern void Ce1Init( void );
|
||||||
extern void Ce2Init(void);
|
extern void Ce2Init( void );
|
||||||
extern void NCe3Init(void);
|
extern void NCe3Init( void );
|
||||||
|
|
||||||
extern void RomSave(void);
|
extern void RomSave( void );
|
||||||
extern void HdwSave(void);
|
extern void HdwSave( void );
|
||||||
extern void RamSave(void);
|
extern void RamSave( void );
|
||||||
extern void Ce1Save(void);
|
extern void Ce1Save( void );
|
||||||
extern void Ce2Save(void);
|
extern void Ce2Save( void );
|
||||||
extern void NCe3Save(void);
|
extern void NCe3Save( void );
|
||||||
|
|
||||||
extern Nibble RomRead(Address);
|
extern Nibble RomRead( Address );
|
||||||
extern Nibble HdwRead(Address);
|
extern Nibble HdwRead( Address );
|
||||||
extern Nibble RamRead(Address);
|
extern Nibble RamRead( Address );
|
||||||
extern Nibble Ce1Read(Address);
|
extern Nibble Ce1Read( Address );
|
||||||
extern Nibble Ce2Read(Address);
|
extern Nibble Ce2Read( Address );
|
||||||
extern Nibble NCe3Read(Address);
|
extern Nibble NCe3Read( Address );
|
||||||
|
|
||||||
extern void RomWrite(Address, Nibble);
|
extern void RomWrite( Address, Nibble );
|
||||||
extern void HdwWrite(Address, Nibble);
|
extern void HdwWrite( Address, Nibble );
|
||||||
extern void RamWrite(Address, Nibble);
|
extern void RamWrite( Address, Nibble );
|
||||||
extern void Ce1Write(Address, Nibble);
|
extern void Ce1Write( Address, Nibble );
|
||||||
extern void Ce2Write(Address, Nibble);
|
extern void Ce2Write( Address, Nibble );
|
||||||
extern void NCe3Write(Address, Nibble);
|
extern void NCe3Write( Address, Nibble );
|
||||||
|
|
||||||
extern void RomInit49(void);
|
extern void RomInit49( void );
|
||||||
extern void HdwInit49(void);
|
extern void HdwInit49( void );
|
||||||
extern void RamInit49(void);
|
extern void RamInit49( void );
|
||||||
extern void Ce1Init49(void);
|
extern void Ce1Init49( void );
|
||||||
extern void Ce2Init49(void);
|
extern void Ce2Init49( void );
|
||||||
extern void NCe3Init49(void);
|
extern void NCe3Init49( void );
|
||||||
|
|
||||||
extern void RomSave49(void);
|
extern void RomSave49( void );
|
||||||
extern void HdwSave49(void);
|
extern void HdwSave49( void );
|
||||||
extern void RamSave49(void);
|
extern void RamSave49( void );
|
||||||
extern void Ce1Save49(void);
|
extern void Ce1Save49( void );
|
||||||
extern void Ce2Save49(void);
|
extern void Ce2Save49( void );
|
||||||
extern void NCe3Save49(void);
|
extern void NCe3Save49( void );
|
||||||
|
|
||||||
extern Nibble RomRead49(Address);
|
extern Nibble RomRead49( Address );
|
||||||
extern Nibble HdwRead49(Address);
|
extern Nibble HdwRead49( Address );
|
||||||
extern Nibble RamRead49(Address);
|
extern Nibble RamRead49( Address );
|
||||||
extern Nibble Ce1Read49(Address);
|
extern Nibble Ce1Read49( Address );
|
||||||
extern Nibble Ce2Read49(Address);
|
extern Nibble Ce2Read49( Address );
|
||||||
extern Nibble NCe3Read49(Address);
|
extern Nibble NCe3Read49( Address );
|
||||||
|
|
||||||
extern void RomWrite49(Address, Nibble);
|
extern void RomWrite49( Address, Nibble );
|
||||||
extern void HdwWrite49(Address, Nibble);
|
extern void HdwWrite49( Address, Nibble );
|
||||||
extern void RamWrite49(Address, Nibble);
|
extern void RamWrite49( Address, Nibble );
|
||||||
extern void Ce1Write49(Address, Nibble);
|
extern void Ce1Write49( Address, Nibble );
|
||||||
extern void Ce2Write49(Address, Nibble);
|
extern void Ce2Write49( Address, Nibble );
|
||||||
extern void NCe3Write49(Address, Nibble);
|
extern void NCe3Write49( Address, Nibble );
|
||||||
|
|
||||||
static const struct
|
static const struct {
|
||||||
{
|
const char* hw;
|
||||||
const char *hw;
|
|
||||||
ModDescription description;
|
ModDescription description;
|
||||||
}
|
}
|
||||||
|
|
||||||
table[] =
|
table[] =
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
|
||||||
HP48
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"hp48",
|
|
||||||
|
|
||||||
{
|
/*---------------------------------------------------------------------------
|
||||||
/* name, id, access_prio,
|
HP48
|
||||||
init, save,
|
---------------------------------------------------------------------------*/
|
||||||
read, write,
|
|
||||||
r_config, r_abs_base_addr, r_size,
|
|
||||||
map_flags
|
|
||||||
*/
|
|
||||||
|
|
||||||
{ "ROM (ROM)", 0x00, 0,
|
{"hp48",
|
||||||
RomInit, RomSave,
|
|
||||||
RomRead, RomWrite,
|
|
||||||
MOD_CONFIGURED, 0x00000, 0xFFFFF,
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "Hardware Regs. (HDW)", 0x19, 5,
|
{ /* name, id, access_prio,
|
||||||
HdwInit, HdwSave,
|
init, save,
|
||||||
HdwRead, HdwWrite,
|
read, write,
|
||||||
MOD_SIZE_CONFIGURED, 0x00000, 0x00040,
|
r_config, r_abs_base_addr, r_size,
|
||||||
},
|
map_flags
|
||||||
|
*/
|
||||||
|
|
||||||
{ "Internal RAM (RAM)", 0x03, 4,
|
{
|
||||||
RamInit, RamSave,
|
"ROM (ROM)",
|
||||||
RamRead, RamWrite,
|
0x00,
|
||||||
MOD_UNCONFIGURED, 0, 0,
|
0,
|
||||||
},
|
RomInit,
|
||||||
|
RomSave,
|
||||||
|
RomRead,
|
||||||
|
RomWrite,
|
||||||
|
MOD_CONFIGURED,
|
||||||
|
0x00000,
|
||||||
|
0xFFFFF,
|
||||||
|
},
|
||||||
|
|
||||||
{ "Bank Select (CE1)", 0x05, 2,
|
{
|
||||||
Ce1Init, Ce1Save,
|
"Hardware Regs. (HDW)",
|
||||||
Ce1Read, Ce1Write,
|
0x19,
|
||||||
MOD_UNCONFIGURED, 0, 0,
|
5,
|
||||||
},
|
HdwInit,
|
||||||
|
HdwSave,
|
||||||
|
HdwRead,
|
||||||
|
HdwWrite,
|
||||||
|
MOD_SIZE_CONFIGURED,
|
||||||
|
0x00000,
|
||||||
|
0x00040,
|
||||||
|
},
|
||||||
|
|
||||||
{ "Port 1 Control (CE2)", 0x07, 3,
|
{
|
||||||
Ce2Init, Ce2Save,
|
"Internal RAM (RAM)",
|
||||||
Ce2Read, Ce2Write,
|
0x03,
|
||||||
MOD_UNCONFIGURED, 0, 0,
|
4,
|
||||||
},
|
RamInit,
|
||||||
|
RamSave,
|
||||||
|
RamRead,
|
||||||
|
RamWrite,
|
||||||
|
MOD_UNCONFIGURED,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
{ "Port 2 Control (NCE3)", 0x01, 1,
|
{
|
||||||
NCe3Init, NCe3Save,
|
"Bank Select (CE1)",
|
||||||
NCe3Read, NCe3Write,
|
0x05,
|
||||||
MOD_UNCONFIGURED, 0, 0,
|
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,
|
HP49
|
||||||
init, save,
|
---------------------------------------------------------------------------*/
|
||||||
read, write,
|
|
||||||
r_config, r_abs_base_addr, r_size,
|
|
||||||
map_flags
|
|
||||||
*/
|
|
||||||
|
|
||||||
{ "ROM (ROM)", 0x00, 0,
|
{"hp49",
|
||||||
RomInit49, RomSave49,
|
|
||||||
RomRead49, RomWrite49,
|
|
||||||
MOD_CONFIGURED, 0x00000, 0xFFFFF,
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "Hardware Regs. (HDW)", 0x19, 5,
|
{ /* name, id, access_prio,
|
||||||
HdwInit, HdwSave,
|
init, save,
|
||||||
HdwRead, HdwWrite,
|
read, write,
|
||||||
MOD_SIZE_CONFIGURED, 0x00000, 0x00040,
|
r_config, r_abs_base_addr, r_size,
|
||||||
},
|
map_flags
|
||||||
|
*/
|
||||||
|
|
||||||
{ "IRAM (RAM)", 0x03, 4,
|
{
|
||||||
RamInit49, RamSave49,
|
"ROM (ROM)",
|
||||||
RamRead49, RamWrite49,
|
0x00,
|
||||||
MOD_UNCONFIGURED, 0, 0,
|
0,
|
||||||
},
|
RomInit49,
|
||||||
|
RomSave49,
|
||||||
|
RomRead49,
|
||||||
|
RomWrite49,
|
||||||
|
MOD_CONFIGURED,
|
||||||
|
0x00000,
|
||||||
|
0xFFFFF,
|
||||||
|
},
|
||||||
|
|
||||||
{ "Bank Select (CE1)", 0x05, 2,
|
{
|
||||||
Ce1Init49, Ce1Save49,
|
"Hardware Regs. (HDW)",
|
||||||
Ce1Read49, Ce1Write49,
|
0x19,
|
||||||
MOD_UNCONFIGURED, 0, 0,
|
5,
|
||||||
},
|
HdwInit,
|
||||||
|
HdwSave,
|
||||||
|
HdwRead,
|
||||||
|
HdwWrite,
|
||||||
|
MOD_SIZE_CONFIGURED,
|
||||||
|
0x00000,
|
||||||
|
0x00040,
|
||||||
|
},
|
||||||
|
|
||||||
{ "ERAM Bank 0 (CE2)", 0x07, 3,
|
{
|
||||||
Ce2Init49, Ce2Save49,
|
"IRAM (RAM)",
|
||||||
Ce2Read49, Ce2Write49,
|
0x03,
|
||||||
MOD_UNCONFIGURED, 0, 0,
|
4,
|
||||||
},
|
RamInit49,
|
||||||
|
RamSave49,
|
||||||
|
RamRead49,
|
||||||
|
RamWrite49,
|
||||||
|
MOD_UNCONFIGURED,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
{ "ERAM Bank 1 (NCE3)", 0x01, 1,
|
{
|
||||||
NCe3Init49, NCe3Save49,
|
"Bank Select (CE1)",
|
||||||
NCe3Read49, NCe3Write49,
|
0x05,
|
||||||
MOD_UNCONFIGURED, 0, 0,
|
2,
|
||||||
MOD_MAP_FLAGS_ABS
|
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
|
.title : ModSelectDescription
|
||||||
|
@ -286,32 +349,32 @@ table[] =
|
||||||
string passed as argument.
|
string passed as argument.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
ModSelectDescription(hw)
|
ModSelectDescription(hw)
|
||||||
.input :
|
.input :
|
||||||
const char *hw, hardware configuration string
|
const char *hw, hardware configuration string
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_NO_MATCH
|
MOD_E_NO_MATCH
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 28-Jan-1998, creation
|
1.1, 28-Jan-1998, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void ModSelectDescription(const char *hw)
|
void ModSelectDescription( const char* hw )
|
||||||
{
|
{
|
||||||
int i;
|
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)
|
if ( i == N_DESCRIPTIONS ) {
|
||||||
{
|
ChfCondition MOD_E_NO_MATCH, CHF_ERROR, hw ChfEnd;
|
||||||
ChfCondition MOD_E_NO_MATCH, CHF_ERROR, hw ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
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)
|
x48 source code by Eddie C. Dost (ecd@dressler.de)
|
||||||
|
|
||||||
NOTE: In the current (r1.1) implementation,
|
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
|
.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 "keyb.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
#define OUT_BITS 12
|
#define OUT_BITS 12
|
||||||
|
|
||||||
/* cur_in:
|
/* cur_in:
|
||||||
|
|
||||||
This array contains the current value the CPU IN register will assume
|
This array contains the current value the CPU IN register will assume
|
||||||
for each bit set in the OUT register.
|
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.
|
interrupt request if any key is pressed.
|
||||||
|
|
||||||
NOTE: This function currently (r1.1) always posts an IRQ request; perhaps,
|
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 :
|
.call :
|
||||||
KeybRSI();
|
KeybRSI();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
*
|
*
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 17-Feb-1998, creation
|
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 ?
|
CpuIntRequest( KeybIN( ( OutputRegister )0x1FF ) != ( InputRegister )0 ? INT_REQUEST_IRQ : INT_REQUEST_NONE );
|
||||||
INT_REQUEST_IRQ : INT_REQUEST_NONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : KeybIn
|
.title : KeybIn
|
||||||
|
@ -155,36 +152,35 @@ void KeybRSI(void)
|
||||||
value of the IN register for the given value of the OUT reguster.
|
value of the IN register for the given value of the OUT reguster.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
in = KeybIN(out);
|
in = KeybIN(out);
|
||||||
.input :
|
.input :
|
||||||
OutputRegister out, current value of the OUT register
|
OutputRegister out, current value of the OUT register
|
||||||
.output :
|
.output :
|
||||||
InputRegister in, computed value of the IN register
|
InputRegister in, computed value of the IN register
|
||||||
.status_codes :
|
.status_codes :
|
||||||
*
|
*
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 17-Feb-1998, creation
|
1.1, 17-Feb-1998, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
InputRegister KeybIN(OutputRegister out)
|
InputRegister KeybIN( OutputRegister out )
|
||||||
{
|
{
|
||||||
/* Compute the current value of the IN register */
|
/* Compute the current value of the IN register */
|
||||||
InputRegister in = (InputRegister)0;
|
InputRegister in = ( InputRegister )0;
|
||||||
int bit;
|
int bit;
|
||||||
|
|
||||||
/* For each bit set in the 'out' register, OR the corresponding IN register
|
/* For each bit set in the 'out' register, OR the corresponding IN register
|
||||||
value into 'in'
|
value into 'in'
|
||||||
*/
|
*/
|
||||||
for(bit=0; bit<OUT_BITS; bit++)
|
for ( bit = 0; bit < OUT_BITS; bit++ ) {
|
||||||
{
|
if ( out & 0x01 )
|
||||||
if(out & 0x01) in |= cur_in[bit];
|
in |= cur_in[ bit ];
|
||||||
out >>= 1;
|
out >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : KeybPress
|
.title : KeybPress
|
||||||
|
@ -196,63 +192,57 @@ InputRegister KeybIN(OutputRegister out)
|
||||||
necessary, posts an interrupt request to the CPU.
|
necessary, posts an interrupt request to the CPU.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
KeybPress(key);
|
KeybPress(key);
|
||||||
.input :
|
.input :
|
||||||
const char *key, identifies the key that has been pressed.
|
const char *key, identifies the key that has been pressed.
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_W_BAD_KEY
|
MOD_W_BAD_KEY
|
||||||
MOD_W_BAD_OUT_BIT
|
MOD_W_BAD_OUT_BIT
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 17-Feb-1998, creation
|
1.1, 17-Feb-1998, creation
|
||||||
2.1, 6-Sep-2000,
|
2.1, 6-Sep-2000,
|
||||||
deeply revised to accomodate the new GUI
|
deeply revised to accomodate the new GUI
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void KeybPress(const char *key)
|
void KeybPress( const char* key )
|
||||||
{
|
{
|
||||||
if(strcmp(key, "*") == 0)
|
if ( strcmp( key, "*" ) == 0 ) {
|
||||||
{
|
/* This is the ON key */
|
||||||
/* This is the ON key */
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Set all 0x8000 lines */
|
/* Set all 0x8000 lines */
|
||||||
for(i=0; i<OUT_BITS; i++) cur_in[i] |= 0x8000;
|
for ( i = 0; i < OUT_BITS; i++ )
|
||||||
|
cur_in[ i ] |= 0x8000;
|
||||||
|
|
||||||
/* Post an interrupt request to the CPU */
|
/* Post an interrupt request to the CPU */
|
||||||
CpuIntRequest(INT_REQUEST_NMI);
|
CpuIntRequest( INT_REQUEST_NMI );
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
int in_val, out_bit;
|
||||||
int in_val, out_bit;
|
|
||||||
|
|
||||||
if(sscanf(key, "%x/%x", &out_bit, &in_val) != 2)
|
if ( sscanf( key, "%x/%x", &out_bit, &in_val ) != 2 ) {
|
||||||
{
|
ChfCondition MOD_W_BAD_KEY, CHF_WARNING, key ChfEnd;
|
||||||
ChfCondition MOD_W_BAD_KEY, CHF_WARNING, key ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
else if(out_bit < 0 || out_bit >= OUT_BITS)
|
else if ( out_bit < 0 || out_bit >= OUT_BITS ) {
|
||||||
{
|
ChfCondition MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ChfEnd;
|
||||||
ChfCondition MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Update the cur_in array */
|
||||||
/* Update the cur_in array */
|
cur_in[ out_bit ] |= in_val;
|
||||||
cur_in[out_bit] |= in_val;
|
|
||||||
|
|
||||||
/* Post an interrupt request to the CPU */
|
/* Post an interrupt request to the CPU */
|
||||||
CpuIntRequest(INT_REQUEST_NMI);
|
CpuIntRequest( INT_REQUEST_NMI );
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : KeybRelease
|
.title : KeybRelease
|
||||||
|
@ -263,56 +253,51 @@ void KeybPress(const char *key)
|
||||||
released. It updates the internal keyboard status information.
|
released. It updates the internal keyboard status information.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
KeybRelease(key);
|
KeybRelease(key);
|
||||||
.input :
|
.input :
|
||||||
const char *key, identifies the key that has been released.
|
const char *key, identifies the key that has been released.
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_W_BAD_KEY
|
MOD_W_BAD_KEY
|
||||||
MOD_W_BAD_OUT_BIT
|
MOD_W_BAD_OUT_BIT
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 17-Feb-1998, creation
|
1.1, 17-Feb-1998, creation
|
||||||
2.1, 6-Sep-2000,
|
2.1, 6-Sep-2000,
|
||||||
deeply revised to accomodate the new GUI
|
deeply revised to accomodate the new GUI
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void KeybRelease(const char *key)
|
void KeybRelease( const char* key )
|
||||||
{
|
{
|
||||||
if(strcmp(key, "*") == 0)
|
if ( strcmp( key, "*" ) == 0 ) {
|
||||||
{
|
/* This is the ON key */
|
||||||
/* This is the ON key */
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Reset all 0x8000 lines */
|
/* Reset all 0x8000 lines */
|
||||||
for(i=0; i<OUT_BITS; i++) cur_in[i] &= 0x7FFF;
|
for ( i = 0; i < OUT_BITS; i++ )
|
||||||
|
cur_in[ i ] &= 0x7FFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
int in_val, out_bit;
|
||||||
int in_val, out_bit;
|
|
||||||
|
|
||||||
if(sscanf(key, "%x/%x", &out_bit, &in_val) != 2)
|
if ( sscanf( key, "%x/%x", &out_bit, &in_val ) != 2 ) {
|
||||||
{
|
ChfCondition MOD_W_BAD_KEY, CHF_WARNING, key ChfEnd;
|
||||||
ChfCondition MOD_W_BAD_KEY, CHF_WARNING, key ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
else if(out_bit < 0 || out_bit >= OUT_BITS)
|
else if ( out_bit < 0 || out_bit >= OUT_BITS ) {
|
||||||
{
|
ChfCondition MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ChfEnd;
|
||||||
ChfCondition MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Update the cur_in array */
|
||||||
/* Update the cur_in array */
|
cur_in[ out_bit ] &= ~in_val;
|
||||||
cur_in[out_bit] &= ~in_val;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : KeybReset
|
.title : KeybReset
|
||||||
|
@ -322,20 +307,21 @@ void KeybRelease(const char *key)
|
||||||
This function resets the emulated keyboard; all keys are released.
|
This function resets the emulated keyboard; all keys are released.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
KeybReset();
|
KeybReset();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
.notes :
|
.notes :
|
||||||
3.13, 7-Nov-2000, creation
|
3.13, 7-Nov-2000, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void KeybReset(void)
|
void KeybReset( void )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Reset all 0x8000 lines */
|
/* 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);
|
void KeybRSI( void );
|
||||||
InputRegister KeybIN(OutputRegister out);
|
InputRegister KeybIN( OutputRegister out );
|
||||||
void KeybPress(const char *key);
|
void KeybPress( const char* key );
|
||||||
void KeybRelease(const char *key);
|
void KeybRelease( const char* key );
|
||||||
void KeybReset(void);
|
void KeybReset( void );
|
||||||
|
|
382
src/libChf/Chf.h
382
src/libChf/Chf.h
|
@ -51,321 +51,263 @@
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Win32 & UNICODE support
|
Win32 & UNICODE support
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define ChfChar TCHAR
|
# define ChfChar TCHAR
|
||||||
#define ChfText(x) _T(x)
|
# define ChfText( x ) _T( x )
|
||||||
#define ChfSigjmp_buf jmp_buf
|
# define ChfSigjmp_buf jmp_buf
|
||||||
#define ChfSigsetjmp(x,y) setjmp(x)
|
# define ChfSigsetjmp( x, y ) setjmp( x )
|
||||||
#define ChfSiglongjmp(x,y) longjmp(x,y)
|
# define ChfSiglongjmp( x, y ) longjmp( x, y )
|
||||||
#else
|
#else
|
||||||
#define ChfChar char
|
# define ChfChar char
|
||||||
#define ChfText(x) x
|
# define ChfText( x ) x
|
||||||
#define ChfSigjmp_buf sigjmp_buf
|
# define ChfSigjmp_buf sigjmp_buf
|
||||||
#define ChfSigsetjmp(x,y) sigsetjmp(x,y)
|
# define ChfSigsetjmp( x, y ) sigsetjmp( x, y )
|
||||||
#define ChfSiglongjmp(x,y) siglongjmp(x,y)
|
# define ChfSiglongjmp( x, y ) siglongjmp( x, y )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
CHF implementation limits and other symbolic constants
|
CHF implementation limits and other symbolic constants
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define CHF_MAX_MESSAGE_LENGTH 256
|
#define CHF_MAX_MESSAGE_LENGTH 256
|
||||||
#define CHF_UNKNOWN_LINE_NUMBER (-1)
|
#define CHF_UNKNOWN_LINE_NUMBER ( -1 )
|
||||||
#define CHF_UNKNOWN_FILE_NAME (ChfChar *)NULL
|
#define CHF_UNKNOWN_FILE_NAME ( ChfChar* )NULL
|
||||||
#define CHF_NULL_DESCRIPTOR (ChfDescriptor *)NULL
|
#define CHF_NULL_DESCRIPTOR ( ChfDescriptor* )NULL
|
||||||
#define CHF_NULL_CONTEXT (void *)NULL
|
#define CHF_NULL_CONTEXT ( void* )NULL
|
||||||
#define CHF_NULL_POINTER (ChfPointer *)NULL
|
#define CHF_NULL_POINTER ( ChfPointer* )NULL
|
||||||
#define CHF_NULL_HANDLER (ChfHandler)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_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_MAJOR_RELEASE_NUMBER 2
|
||||||
#define CHF_MINOR_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_MODULE_NAMES_SET 1
|
||||||
|
#define CHF_SET 2
|
||||||
|
#define CHF_ERRNO_SET 3
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Condition codes
|
Condition codes
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define CHF_S_OK 0
|
#define CHF_S_OK 0
|
||||||
#define CHF_F_COND_STACK_FULL 1 /* Condition stack is full */
|
#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_FULL 2 /* Handler stack is full */
|
||||||
#define CHF_F_HDLR_STACK_EMPTY 3 /* Handler stack is empty */
|
#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_BAD_STATE 4 /* Bad CHF state for req. operation */
|
||||||
#define CHF_F_INVALID_ACTION 5 /* Invalid action from handler: %d */
|
#define CHF_F_INVALID_ACTION 5 /* Invalid action from handler: %d */
|
||||||
#define CHF_F_MALLOC 6 /* Dynamic memory allocation failed */
|
#define CHF_F_MALLOC 6 /* Dynamic memory allocation failed */
|
||||||
#define CHF_F_NOT_AVAILABLE 7 /* Function not available */
|
#define CHF_F_NOT_AVAILABLE 7 /* Function not available */
|
||||||
#define CHF_F_SETLOCALE 10 /* setlocale() failed */
|
#define CHF_F_SETLOCALE 10 /* setlocale() failed */
|
||||||
#define CHF_F_CATOPEN 11 /* catopen() failed */
|
#define CHF_F_CATOPEN 11 /* catopen() failed */
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Type definitions
|
Type definitions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef enum /* Condition severity codes */
|
typedef enum /* Condition severity codes */
|
||||||
{
|
{ CHF_SUCCESS,
|
||||||
CHF_SUCCESS,
|
|
||||||
CHF_INFO,
|
CHF_INFO,
|
||||||
CHF_WARNING,
|
CHF_WARNING,
|
||||||
CHF_ERROR,
|
CHF_ERROR,
|
||||||
CHF_FATAL
|
CHF_FATAL } ChfSeverity;
|
||||||
}
|
|
||||||
ChfSeverity;
|
|
||||||
|
|
||||||
typedef enum /* Condition handler action codes */
|
typedef enum /* Condition handler action codes */
|
||||||
{
|
{ CHF_CONTINUE, /* Continue application */
|
||||||
CHF_CONTINUE, /* Continue application */
|
CHF_RESIGNAL, /* Resignal to next handler */
|
||||||
CHF_RESIGNAL, /* Resignal to next handler */
|
CHF_UNWIND, /* Stack unwind */
|
||||||
CHF_UNWIND, /* Stack unwind */
|
CHF_UNWIND_KEEP /* Unwind, keep last cond. group */
|
||||||
CHF_UNWIND_KEEP /* Unwind, keep last cond. group */
|
} ChfAction;
|
||||||
}
|
|
||||||
ChfAction;
|
|
||||||
|
|
||||||
typedef int /* CHF options */
|
typedef int /* CHF options */
|
||||||
ChfOptions;
|
ChfOptions;
|
||||||
|
|
||||||
#define CHF_DEFAULT 0x0000 /* default flags */
|
#define CHF_DEFAULT 0x0000 /* default flags */
|
||||||
#define CHF_ABORT 0x0001 /* use abort() instead of exit() */
|
#define CHF_ABORT 0x0001 /* use abort() instead of exit() */
|
||||||
|
|
||||||
typedef enum /* Current CHF state */
|
typedef enum /* Current CHF state */
|
||||||
{
|
{ CHF_UNKNOWN,
|
||||||
CHF_UNKNOWN,
|
|
||||||
CHF_IDLE,
|
CHF_IDLE,
|
||||||
CHF_SIGNALING,
|
CHF_SIGNALING,
|
||||||
CHF_UNWINDING,
|
CHF_UNWINDING,
|
||||||
CHF_SIGNAL_UNWINDING
|
CHF_SIGNAL_UNWINDING } ChfState;
|
||||||
}
|
|
||||||
ChfState;
|
|
||||||
|
|
||||||
typedef struct ChfDescriptor_S /* Condition descriptor */
|
typedef struct ChfDescriptor_S /* Condition descriptor */
|
||||||
{
|
{
|
||||||
int module_id; /* Module identifier */
|
int module_id; /* Module identifier */
|
||||||
int condition_code; /* Condition code */
|
int condition_code; /* Condition code */
|
||||||
ChfSeverity severity; /* Severity */
|
ChfSeverity severity; /* Severity */
|
||||||
int line_number; /* Line # or CHF_UNK_LINE_NUMBER */
|
int line_number; /* Line # or CHF_UNK_LINE_NUMBER */
|
||||||
const ChfChar *file_name; /* File name or CHF_UNK_FILE_NAME */
|
const ChfChar* file_name; /* File name or CHF_UNK_FILE_NAME */
|
||||||
ChfChar message[CHF_MAX_MESSAGE_LENGTH]; /* Partial message */
|
ChfChar message[ CHF_MAX_MESSAGE_LENGTH ]; /* Partial message */
|
||||||
struct ChfDescriptor_S *next; /* Link to next descriptor */
|
struct ChfDescriptor_S* next; /* Link to next descriptor */
|
||||||
}
|
} ChfDescriptor;
|
||||||
ChfDescriptor;
|
|
||||||
|
|
||||||
typedef struct ChfTable_S /* Standalone message table */
|
typedef struct ChfTable_S /* Standalone message table */
|
||||||
{
|
{
|
||||||
int module; /* Module identifier */
|
int module; /* Module identifier */
|
||||||
int code; /* Condition code */
|
int code; /* Condition code */
|
||||||
ChfChar *msg_template; /* Message template */
|
ChfChar* msg_template; /* Message template */
|
||||||
}
|
} ChfTable;
|
||||||
ChfTable;
|
|
||||||
|
|
||||||
typedef /* Generic pointer */
|
typedef /* Generic pointer */
|
||||||
void *ChfPointer;
|
void* ChfPointer;
|
||||||
|
|
||||||
typedef /* Condition handler */
|
typedef /* Condition handler */
|
||||||
ChfAction (*ChfHandler)(
|
ChfAction ( *ChfHandler )( const ChfDescriptor*, const ChfState, ChfPointer );
|
||||||
const ChfDescriptor *,
|
|
||||||
const ChfState,
|
|
||||||
ChfPointer
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef /* Message retrieval 'get_message' function */
|
typedef /* Message retrieval 'get_message' function */
|
||||||
const ChfChar * (*ChfMrsGet)(
|
const ChfChar* ( *ChfMrsGet )( void*, const int, const int, const ChfChar* default_message );
|
||||||
void *,
|
|
||||||
const int,
|
|
||||||
const int,
|
|
||||||
const ChfChar *default_message
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef /* Message retrieval 'exit' function */
|
|
||||||
void (*ChfMrsExit)(
|
|
||||||
void *
|
|
||||||
);
|
|
||||||
|
|
||||||
|
typedef /* Message retrieval 'exit' function */
|
||||||
|
void ( *ChfMrsExit )( void* );
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Condition generation macros
|
Condition generation macros
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#if defined(CHF_EXTENDED_INFO)
|
#if defined( CHF_EXTENDED_INFO )
|
||||||
#define ChfCondition \
|
# define ChfCondition \
|
||||||
ChfGenerate( \
|
ChfGenerate( \
|
||||||
CHF_MODULE_ID, \
|
CHF_MODULE_ID, \
|
||||||
ChfText(__FILE__), __LINE__,
|
ChfText(__FILE__), __LINE__,
|
||||||
|
|
||||||
#ifdef _WIN32
|
# ifdef _WIN32
|
||||||
#define ChfErrnoCondition
|
# define ChfErrnoCondition
|
||||||
#else
|
# else
|
||||||
#define ChfErrnoCondition \
|
# define ChfErrnoCondition ChfGenerate( CHF_ERRNO_SET, ChfText( __FILE__ ), __LINE__, errno, CHF_ERROR )
|
||||||
ChfGenerate( \
|
# endif
|
||||||
CHF_ERRNO_SET, \
|
|
||||||
ChfText(__FILE__), __LINE__, \
|
|
||||||
errno, \
|
|
||||||
CHF_ERROR \
|
|
||||||
)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define ChfCondition \
|
# define ChfCondition \
|
||||||
ChfGenerate( \
|
ChfGenerate( \
|
||||||
CHF_MODULE_ID, \
|
CHF_MODULE_ID, \
|
||||||
CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER,
|
CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER,
|
||||||
|
|
||||||
#ifdef _WIN32
|
# ifdef _WIN32
|
||||||
#define ChfErrnoCondition
|
# define ChfErrnoCondition
|
||||||
#else
|
# else
|
||||||
#define ChfErrnoCondition \
|
# define ChfErrnoCondition ChfGenerate( CHF_ERRNO_SET, CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER, errno, CHF_ERROR )
|
||||||
ChfGenerate( \
|
# endif
|
||||||
CHF_ERRNO_SET, \
|
|
||||||
CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER, \
|
|
||||||
errno, \
|
|
||||||
CHF_ERROR \
|
|
||||||
)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ChfEnd \
|
#define ChfEnd \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Structured condition handling
|
Structured condition handling
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define ChfTry \
|
#define ChfTry \
|
||||||
{\
|
{ \
|
||||||
ChfSigjmp_buf _chf_sigjmp_buf;\
|
ChfSigjmp_buf _chf_sigjmp_buf; \
|
||||||
if(ChfSigsetjmp(_chf_sigjmp_buf, 1) == 0)\
|
if ( ChfSigsetjmp( _chf_sigjmp_buf, 1 ) == 0 ) { \
|
||||||
{\
|
ChfPushHandler( CHF_NULL_HANDLER, _chf_sigjmp_buf, CHF_NULL_POINTER );
|
||||||
ChfPushHandler(CHF_NULL_HANDLER, _chf_sigjmp_buf, CHF_NULL_POINTER);
|
|
||||||
|
|
||||||
#define ChfCatch \
|
#define ChfCatch \
|
||||||
ChfPopHandler();\
|
ChfPopHandler(); \
|
||||||
}\
|
} \
|
||||||
else\
|
else \
|
||||||
{
|
{
|
||||||
|
|
||||||
#define ChfEndTry \
|
#define ChfEndTry \
|
||||||
ChfDiscard();\
|
ChfDiscard(); \
|
||||||
}\
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Other macros
|
Other macros
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define ChfGetNextDescriptor(d) (d)->next
|
#define ChfGetNextDescriptor( d ) ( d )->next
|
||||||
#define ChfGetModuleId(d) (d)->module_id
|
#define ChfGetModuleId( d ) ( d )->module_id
|
||||||
#define ChfGetConditionCode(d) (d)->condition_code
|
#define ChfGetConditionCode( d ) ( d )->condition_code
|
||||||
#define ChfGetSeverity(d) (d)->severity
|
#define ChfGetSeverity( d ) ( d )->severity
|
||||||
#define ChfGetLineNumber(d) (d)->line_number
|
#define ChfGetLineNumber( d ) ( d )->line_number
|
||||||
#define ChfGetFileName(d) (d)->file_name
|
#define ChfGetFileName( d ) ( d )->file_name
|
||||||
#define ChfGetPartialMessage(d) (d)->message
|
#define ChfGetPartialMessage( d ) ( d )->message
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Function prototypes
|
Function prototypes
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int ChfInit( /* Generic initialization */
|
int ChfInit( /* Generic initialization */
|
||||||
const ChfChar *app_name, /* Application's name */
|
const ChfChar* app_name, /* Application's name */
|
||||||
const ChfOptions options, /* Options */
|
const ChfOptions options, /* Options */
|
||||||
void *mrs_data, /* Message retrieval private data */
|
void* mrs_data, /* Message retrieval private data */
|
||||||
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
||||||
ChfMrsExit mrs_exit, /* 'Exit' function */
|
ChfMrsExit mrs_exit, /* 'Exit' function */
|
||||||
const int condition_stack_size, /* Size of the condition stack */
|
const int condition_stack_size, /* Size of the condition stack */
|
||||||
const int handler_stack_size, /* Size of the handler stack */
|
const int handler_stack_size, /* Size of the handler stack */
|
||||||
const int exit_code /* Abnormal exit code */
|
const int exit_code /* Abnormal exit code */
|
||||||
);
|
);
|
||||||
|
|
||||||
int ChfMsgcatInit( /* Initialization with msgcat subsystem */
|
int ChfMsgcatInit( /* Initialization with msgcat subsystem */
|
||||||
const ChfChar *app_name, /* Application's name */
|
const ChfChar* app_name, /* Application's name */
|
||||||
const ChfOptions options, /* Options */
|
const ChfOptions options, /* Options */
|
||||||
const ChfChar *msgcat_name, /* Name of the message catalog */
|
const ChfChar* msgcat_name, /* Name of the message catalog */
|
||||||
const int condition_stack_size, /* Size of the condition stack */
|
const int condition_stack_size, /* Size of the condition stack */
|
||||||
const int handler_stack_size, /* Size of the handler stack */
|
const int handler_stack_size, /* Size of the handler stack */
|
||||||
const int exit_code /* Abnormal exit code */
|
const int exit_code /* Abnormal exit code */
|
||||||
);
|
);
|
||||||
|
|
||||||
int ChfStaticInit( /* Initialization with static message tables */
|
int ChfStaticInit( /* Initialization with static message tables */
|
||||||
const ChfChar *app_name, /* Application's name */
|
const ChfChar* app_name, /* Application's name */
|
||||||
const ChfOptions options, /* Options */
|
const ChfOptions options, /* Options */
|
||||||
const ChfTable *table, /* Static message table */
|
const ChfTable* table, /* Static message table */
|
||||||
const size_t table_size, /* Size of the message table */
|
const size_t table_size, /* Size of the message table */
|
||||||
const int condition_stack_size, /* Size of the condition stack */
|
const int condition_stack_size, /* Size of the condition stack */
|
||||||
const int handler_stack_size, /* Size of the handler stack */
|
const int handler_stack_size, /* Size of the handler stack */
|
||||||
const int exit_code /* Abnormal exit code */
|
const int exit_code /* Abnormal exit code */
|
||||||
);
|
);
|
||||||
|
|
||||||
int ChfWin32Init( /* Initialization within _WIN32 */
|
int ChfWin32Init( /* Initialization within _WIN32 */
|
||||||
const ChfChar *app_name, /* Application's name */
|
const ChfChar* app_name, /* Application's name */
|
||||||
const ChfOptions options, /* Options */
|
const ChfOptions options, /* Options */
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
void *instance, /* Fake arguments */
|
void* instance, /* Fake arguments */
|
||||||
#else
|
#else
|
||||||
HINSTANCE instance, /* App. instance handle */
|
HINSTANCE instance, /* App. instance handle */
|
||||||
#endif
|
#endif
|
||||||
const int condition_stack_size, /* Size of the condition stack */
|
const int condition_stack_size, /* Size of the condition stack */
|
||||||
const int handler_stack_size, /* Size of the handler stack */
|
const int handler_stack_size, /* Size of the handler stack */
|
||||||
const int exit_code /* Abnormal exit code */
|
const int exit_code /* Abnormal exit code */
|
||||||
);
|
);
|
||||||
|
|
||||||
void ChfExit( /* Exit */
|
void ChfExit( /* Exit */
|
||||||
void
|
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 */
|
void ChfPopHandler( /* Pop a handler */
|
||||||
const int abort_code
|
void );
|
||||||
);
|
|
||||||
|
|
||||||
void ChfPushHandler( /* Push a new handler into the stack */
|
ChfChar* ChfBuildMessage( /* Build a condition message */
|
||||||
ChfHandler new_handler, /* Handler to be added */
|
const ChfDescriptor* descriptor );
|
||||||
void *unwind_context, /* Unwind context */
|
|
||||||
ChfPointer handler_context /* Private handler context */
|
|
||||||
);
|
|
||||||
|
|
||||||
void ChfPopHandler( /* Pop a handler */
|
void ChfSignal( /* Signal the current conditions */
|
||||||
void
|
void );
|
||||||
);
|
|
||||||
|
|
||||||
ChfChar *ChfBuildMessage( /* Build a condition message */
|
void ChfDiscard( /* Discard the current conditions */
|
||||||
const ChfDescriptor *descriptor
|
void );
|
||||||
);
|
|
||||||
|
|
||||||
void ChfSignal( /* Signal the current conditions */
|
void ChfGenerate( /* Generate a condition into the stack */
|
||||||
void
|
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 */
|
const ChfChar* ChfGetMessage( /* Retrieve a condition message */
|
||||||
void
|
const int module_id, const int condition_code, const ChfChar* default_message );
|
||||||
);
|
|
||||||
|
|
||||||
void ChfGenerate( /* Generate a condition into the stack */
|
const ChfDescriptor* ChfGetTopCondition( /* Retrieve top condition */
|
||||||
const int module_id,
|
void );
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
|
@ -37,119 +37,110 @@
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Macros
|
Macros
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define CHF_MODULE_ID CHF_SET
|
#define CHF_MODULE_ID CHF_SET
|
||||||
#define CHF_TMP_MESSAGE_LENGTH (2*CHF_MAX_MESSAGE_LENGTH)
|
#define CHF_TMP_MESSAGE_LENGTH ( 2 * CHF_MAX_MESSAGE_LENGTH )
|
||||||
#define CHF_DEF_MESSAGE_LENGTH 40
|
#define CHF_DEF_MESSAGE_LENGTH 40
|
||||||
#define CHF_DEF_PARTIAL_MSG_FMT ChfText("Code <%d>d")
|
#define CHF_DEF_PARTIAL_MSG_FMT ChfText( "Code <%d>d" )
|
||||||
#define CHF_DEF_MID_MSG_FMT ChfText("Mid <%d>d")
|
#define CHF_DEF_MID_MSG_FMT ChfText( "Mid <%d>d" )
|
||||||
#define CHF_EXTENDED_INFO_FMT ChfText("(%s,%d)")
|
#define CHF_EXTENDED_INFO_FMT ChfText( "(%s,%d)" )
|
||||||
#define CHF_SEVERITY_NAMES \
|
#define CHF_SEVERITY_NAMES \
|
||||||
{ ChfText("S"), ChfText("I"), ChfText("W"), ChfText("E"), ChfText("F") }
|
{ \
|
||||||
#define CHF_UNKNOWN_SEVERITY ChfText("?")
|
ChfText( "S" ), ChfText( "I" ), ChfText( "W" ), ChfText( "E" ), ChfText( "F" ) \
|
||||||
#define CHF_MESSAGE_SEPARATOR ChfText("-")
|
}
|
||||||
#define CHF_MESSAGE_TERMINATOR ChfText("\n")
|
#define CHF_UNKNOWN_SEVERITY ChfText( "?" )
|
||||||
#define CHF_ABORT_HEADER ChfText("ChfAbort-F-")
|
#define CHF_MESSAGE_SEPARATOR ChfText( "-" )
|
||||||
#define CHF_ABORT_BAD_CODE_FMT ChfText("Bad abort code <%d>d\n")
|
#define CHF_MESSAGE_TERMINATOR ChfText( "\n" )
|
||||||
#define CHF_ABORT_GOOD_CODE_FMT ChfText("%s\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_SILENT 0
|
||||||
#define CHF_ABORT_INIT 1
|
#define CHF_ABORT_INIT 1
|
||||||
#define CHF_ABORT_MSG_OVF 2
|
#define CHF_ABORT_MSG_OVF 2
|
||||||
#define CHF_ABORT_INVALID_ACTION 3
|
#define CHF_ABORT_INVALID_ACTION 3
|
||||||
#define CHF_ABORT_DUP_INIT 4
|
#define CHF_ABORT_DUP_INIT 4
|
||||||
#define CHF_ABORT_ALREADY_UNWINDING 5
|
#define CHF_ABORT_ALREADY_UNWINDING 5
|
||||||
#define CHF_ABORT_IMPROPERLY_HANDLED 6
|
#define CHF_ABORT_IMPROPERLY_HANDLED 6
|
||||||
#define CHF_ABORT_FATAL_UNWINDING 7
|
#define CHF_ABORT_FATAL_UNWINDING 7
|
||||||
#define CHF_ABORT_COND_STACK_OVF 8
|
#define CHF_ABORT_COND_STACK_OVF 8
|
||||||
#define CHF_ABORT_GET_CONTEXT 9
|
#define CHF_ABORT_GET_CONTEXT 9
|
||||||
#define CHF_ABORT_PTHREAD 10
|
#define CHF_ABORT_PTHREAD 10
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Type definitions
|
Type definitions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct ChfHandlerDescriptor_S
|
typedef struct ChfHandlerDescriptor_S {
|
||||||
{
|
ChfHandler handler;
|
||||||
ChfHandler handler;
|
void* unwind_context;
|
||||||
void *unwind_context;
|
ChfPointer handler_context;
|
||||||
ChfPointer handler_context;
|
} ChfHandlerDescriptor;
|
||||||
}
|
|
||||||
ChfHandlerDescriptor;
|
|
||||||
|
|
||||||
typedef struct ChfContext_S /* CHF Context */
|
typedef struct ChfContext_S /* CHF Context */
|
||||||
{
|
{
|
||||||
ChfState state; /* Current CHF state */
|
ChfState state; /* Current CHF state */
|
||||||
const ChfChar *app_name; /* Application's name */
|
const ChfChar* app_name; /* Application's name */
|
||||||
ChfOptions options; /* Options */
|
ChfOptions options; /* Options */
|
||||||
void *mrs_data; /* Message retrieval private data */
|
void* mrs_data; /* Message retrieval private data */
|
||||||
ChfMrsGet mrs_get; /* 'GetMessage' function */
|
ChfMrsGet mrs_get; /* 'GetMessage' function */
|
||||||
ChfMrsExit mrs_exit; /* 'Exit' function */
|
ChfMrsExit mrs_exit; /* 'Exit' function */
|
||||||
int condition_stack_size; /* Size of the condition stack */
|
int condition_stack_size; /* Size of the condition stack */
|
||||||
int handler_stack_size; /* Size of the handler stack */
|
int handler_stack_size; /* Size of the handler stack */
|
||||||
int exit_code; /* Abnormal exit code */
|
int exit_code; /* Abnormal exit code */
|
||||||
ChfDescriptor *condition_stack; /* Condition stack */
|
ChfDescriptor* condition_stack; /* Condition stack */
|
||||||
ChfDescriptor *condition_base; /* Current condition stack base */
|
ChfDescriptor* condition_base; /* Current condition stack base */
|
||||||
ChfDescriptor *condition_sp; /* Current condition stack pointer */
|
ChfDescriptor* condition_sp; /* Current condition stack pointer */
|
||||||
ChfHandlerDescriptor *handler_stack; /* Handler stack */
|
ChfHandlerDescriptor* handler_stack; /* Handler stack */
|
||||||
ChfHandlerDescriptor *handler_sp; /* Current handler stack pointer */
|
ChfHandlerDescriptor* handler_sp; /* Current handler stack pointer */
|
||||||
ChfChar *message_buffer; /* Message buffer */
|
ChfChar* message_buffer; /* Message buffer */
|
||||||
}
|
} ChfContext;
|
||||||
ChfContext;
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Multithreading support
|
Multithreading support
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#define chf_context (*_ChfGetContext())
|
# define chf_context ( *_ChfGetContext() )
|
||||||
#else
|
#else
|
||||||
#define chf_context _chf_context
|
# define chf_context _chf_context
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Global variables
|
Global variables
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
extern ChfContext _chf_context; /* CHF Context */
|
extern ChfContext _chf_context; /* CHF Context */
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Private function prototypes
|
Private function prototypes
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
ChfContext *_ChfGetContext(void);
|
ChfContext* _ChfGetContext( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Private redirection of stdlib functions needed by Win32
|
Private redirection of stdlib functions needed by Win32
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define ChfStrlen _tcslen
|
# define ChfStrlen _tcslen
|
||||||
#define ChfStrcpy _tcscpy
|
# define ChfStrcpy _tcscpy
|
||||||
#define ChfStrcat _tcscat
|
# define ChfStrcat _tcscat
|
||||||
#define ChfStrncpy _tcsncpy
|
# define ChfStrncpy _tcsncpy
|
||||||
#define ChfSprintf _stprintf
|
# define ChfSprintf _stprintf
|
||||||
#define ChfVsprintf _vstprintf
|
# define ChfVsprintf _vstprintf
|
||||||
#else
|
#else
|
||||||
#define ChfStrlen strlen
|
# define ChfStrlen strlen
|
||||||
#define ChfStrcpy strcpy
|
# define ChfStrcpy strcpy
|
||||||
#define ChfStrcat strcat
|
# define ChfStrcat strcat
|
||||||
#define ChfStrncpy strncpy
|
# define ChfStrncpy strncpy
|
||||||
#define ChfSprintf sprintf
|
# define ChfSprintf sprintf
|
||||||
#define ChfVsprintf vsprintf
|
# define ChfVsprintf vsprintf
|
||||||
#endif
|
#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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <errno.h>
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#include <tchar.h>
|
# include <tchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
#include "ChfPriv.h"
|
#include "ChfPriv.h"
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Abort codes message table; the relative position of the messages must
|
/* Abort codes message table; the relative position of the messages must
|
||||||
match the numeric codes CHF_ABORT_xxxx defined in ChfPriv.h
|
match the numeric codes CHF_ABORT_xxxx defined in ChfPriv.h
|
||||||
*/
|
*/
|
||||||
static const ChfChar *message_table[] =
|
static const ChfChar* message_table[] = { ( const ChfChar* )NULL,
|
||||||
{
|
ChfText( "Not initialized" ),
|
||||||
(const ChfChar *)NULL,
|
ChfText( "Temporary message buffer overflow" ),
|
||||||
ChfText("Not initialized"),
|
ChfText( "Invalid action from last chance handler" ),
|
||||||
ChfText("Temporary message buffer overflow"),
|
ChfText( "Already initialized" ),
|
||||||
ChfText("Invalid action from last chance handler"),
|
ChfText( "Unwind request while unwinding" ),
|
||||||
ChfText("Already initialized"),
|
ChfText( "Improperly handled condition" ),
|
||||||
ChfText("Unwind request while unwinding"),
|
ChfText( "Fatal condition while unwinding" ),
|
||||||
ChfText("Improperly handled condition"),
|
ChfText( "Condition stack overflow" ),
|
||||||
ChfText("Fatal condition while unwinding"),
|
ChfText( "Can't prime a new Chf context" ),
|
||||||
ChfText("Condition stack overflow"),
|
ChfText( "Pthread interaction failed" ) };
|
||||||
ChfText("Can't prime a new Chf context"),
|
|
||||||
ChfText("Pthread interaction failed")
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MESSAGE_TABLE_SIZE (sizeof(message_table)/sizeof(const ChfChar *))
|
|
||||||
|
|
||||||
|
#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.
|
application when a CHF_FATAL condition occours.
|
||||||
|
|
||||||
NOTE: This function must be called only when either a serious internal CHF
|
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:
|
WIN32:
|
||||||
|
|
||||||
|
@ -107,13 +102,13 @@ static const ChfChar *message_table[] =
|
||||||
- abort() is not supported and has been replaced by exit(EXIT_FAILURE)
|
- abort() is not supported and has been replaced by exit(EXIT_FAILURE)
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
ChfAbort(abort_code);
|
ChfAbort(abort_code);
|
||||||
.input :
|
.input :
|
||||||
const int abort_code, abort_code
|
const int abort_code, abort_code
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
none
|
none
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 13-May-1996, creation
|
1.1, 13-May-1996, creation
|
||||||
2.1, 19-May-2000, update:
|
2.1, 19-May-2000, update:
|
||||||
|
@ -122,78 +117,66 @@ static const ChfChar *message_table[] =
|
||||||
- added Win32 support
|
- added Win32 support
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void ChfAbort( /* Abort application */
|
void ChfAbort( /* Abort application */
|
||||||
const int abort_code
|
const int abort_code )
|
||||||
)
|
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if(abort_code != CHF_ABORT_SILENT)
|
if ( abort_code != CHF_ABORT_SILENT ) {
|
||||||
{
|
TCHAR abort_msg[ CHF_MAX_MESSAGE_LENGTH ];
|
||||||
TCHAR abort_msg[CHF_MAX_MESSAGE_LENGTH];
|
HWND active_window;
|
||||||
HWND active_window;
|
|
||||||
|
|
||||||
/* stderr not available;
|
/* stderr not available;
|
||||||
put complaint in a message box and display it
|
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)
|
if ( chf_context.state == CHF_UNKNOWN || chf_context.options & CHF_ABORT )
|
||||||
_stprintf(abort_msg,
|
exit( EXIT_FAILURE );
|
||||||
CHF_ABORT_BAD_CODE_FMT, abort_code);
|
|
||||||
|
|
||||||
else
|
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
|
/* Else, exit the application anyway, but with the exit code
|
||||||
registered by the application. Don't use PostQuitMessage(),
|
registered by the application. Don't use PostQuitMessage(),
|
||||||
because the contract is that ChfAbort() never returns to the caller.
|
because the contract is that ChfAbort() never returns to the caller.
|
||||||
*/
|
*/
|
||||||
#ifndef _REENTRANT
|
# ifndef _REENTRANT
|
||||||
exit(chf_context.exit_code);
|
exit( chf_context.exit_code );
|
||||||
#else
|
# else
|
||||||
#error "_REENTRANT not supported yet"
|
# error "_REENTRANT not supported yet"
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if(abort_code != CHF_ABORT_SILENT)
|
if ( abort_code != CHF_ABORT_SILENT ) {
|
||||||
{
|
fputs( CHF_ABORT_HEADER, stderr );
|
||||||
fputs(CHF_ABORT_HEADER, stderr);
|
|
||||||
|
|
||||||
if(abort_code < 0 || abort_code >= MESSAGE_TABLE_SIZE)
|
if ( abort_code < 0 || abort_code >= MESSAGE_TABLE_SIZE )
|
||||||
fprintf(stderr, CHF_ABORT_BAD_CODE_FMT, abort_code);
|
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
|
else
|
||||||
fprintf(stderr, CHF_ABORT_GOOD_CODE_FMT, message_table[abort_code]);
|
# ifndef _REENTRANT
|
||||||
}
|
exit( chf_context.exit_code );
|
||||||
|
# else
|
||||||
if(chf_context.state == CHF_UNKNOWN || chf_context.options & CHF_ABORT)
|
pthread_exit( ( void* )( chf_context.exit_code ) );
|
||||||
abort();
|
# endif
|
||||||
|
|
||||||
else
|
|
||||||
#ifndef _REENTRANT
|
|
||||||
exit(chf_context.exit_code);
|
|
||||||
#else
|
|
||||||
pthread_exit((void *)(chf_context.exit_code));
|
|
||||||
#endif
|
|
||||||
#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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <errno.h>
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#include <tchar.h>
|
# include <tchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
#include "ChfPriv.h"
|
#include "ChfPriv.h"
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ChfGenerate
|
.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.
|
condition stack.
|
||||||
|
|
||||||
NOTE: This function calls the CHF function 'ChfAbort()' to
|
NOTE: This function calls the CHF function 'ChfAbort()' to
|
||||||
abort the application if either:
|
abort the application if either:
|
||||||
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
||||||
- there is an overflow in the internal buffer used during the
|
- there is an overflow in the internal buffer used during the
|
||||||
generation of the partial message associated with the condition
|
generation of the partial message associated with the condition
|
||||||
(abort code CHF_ABORT_MSG_OVF)
|
(abort code CHF_ABORT_MSG_OVF)
|
||||||
- there was an attempt to generate a condition while the CHF condition
|
- there was an attempt to generate a condition while the CHF condition
|
||||||
CHF_F_COND_STACK_FULL (condition stack full) was being signalled
|
CHF_F_COND_STACK_FULL (condition stack full) was being signalled
|
||||||
(abort code CHF_ABORT_COND_STACK_OVF)
|
(abort code CHF_ABORT_COND_STACK_OVF)
|
||||||
|
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
ChfGenerate(module_id, file_name, line_number,
|
ChfGenerate(module_id, file_name, line_number,
|
||||||
condition_code, severity, ...);
|
condition_code, severity, ...);
|
||||||
.input :
|
.input :
|
||||||
const int module_id, module identifier
|
const int module_id, module identifier
|
||||||
const char *file_name, file name
|
const char *file_name, file name
|
||||||
const int line_number, line number
|
const int line_number, line number
|
||||||
const int condition_code, condition code
|
const int condition_code, condition code
|
||||||
const ChfSeverity severity, severity
|
const ChfSeverity severity, severity
|
||||||
..., additional arguments
|
..., additional arguments
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
(*) CHF_F_COND_STACK_FULL, the condition stack is full
|
(*) CHF_F_COND_STACK_FULL, the condition stack is full
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 3-May-1996, creation
|
1.1, 3-May-1996, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void ChfGenerate( /* Generate a condition into the stack */
|
void ChfGenerate( /* Generate a condition into the stack */
|
||||||
const int module_id,
|
const int module_id, const ChfChar* file_name, const int line_number, const int condition_code,
|
||||||
const ChfChar *file_name,
|
const ChfSeverity severity, ... )
|
||||||
const int line_number,
|
|
||||||
const int condition_code,
|
|
||||||
const ChfSeverity severity,
|
|
||||||
...
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ChfDescriptor *new_descriptor;
|
ChfDescriptor* new_descriptor;
|
||||||
va_list aux_arg;
|
va_list aux_arg;
|
||||||
|
|
||||||
/* Check that CHF has been correctly initialized */
|
/* Check that CHF has been correctly initialized */
|
||||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
if ( chf_context.state == CHF_UNKNOWN )
|
||||||
|
ChfAbort( CHF_ABORT_INIT );
|
||||||
|
|
||||||
/* Prepare the additional arguments list */
|
/* Prepare the additional arguments list */
|
||||||
va_start(aux_arg, severity);
|
va_start( aux_arg, severity );
|
||||||
|
|
||||||
if((new_descriptor = chf_context.condition_sp) -
|
if ( ( new_descriptor = chf_context.condition_sp ) - chf_context.condition_stack >= chf_context.condition_stack_size ) {
|
||||||
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,
|
||||||
/* The condition stack is full;
|
using the last available slot of the stack, if it's still empty,
|
||||||
generate the CHF_F_COND_STACK_FULL condition and signal it immediately,
|
otherwise abort the application.
|
||||||
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;
|
||||||
if(new_descriptor - chf_context.condition_stack ==
|
new_descriptor->condition_code = CHF_F_COND_STACK_FULL;
|
||||||
chf_context.condition_stack_size)
|
new_descriptor->severity = CHF_FATAL;
|
||||||
{
|
new_descriptor->line_number = CHF_UNKNOWN_LINE_NUMBER;
|
||||||
new_descriptor->module_id = CHF_MODULE_ID;
|
new_descriptor->file_name = CHF_UNKNOWN_FILE_NAME;
|
||||||
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,
|
ChfStrncpy( new_descriptor->message,
|
||||||
ChfGetMessage(CHF_MODULE_ID, CHF_F_COND_STACK_FULL,
|
ChfGetMessage( CHF_MODULE_ID, CHF_F_COND_STACK_FULL, ChfText( "Condition stack is full" ) ),
|
||||||
ChfText("Condition stack is full")), CHF_MAX_MESSAGE_LENGTH-1);
|
CHF_MAX_MESSAGE_LENGTH - 1 );
|
||||||
new_descriptor->message[CHF_MAX_MESSAGE_LENGTH-1] = '\0';
|
new_descriptor->message[ CHF_MAX_MESSAGE_LENGTH - 1 ] = '\0';
|
||||||
|
|
||||||
new_descriptor->next = CHF_NULL_DESCRIPTOR;
|
new_descriptor->next = CHF_NULL_DESCRIPTOR;
|
||||||
chf_context.condition_sp++;
|
chf_context.condition_sp++;
|
||||||
|
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
ChfAbort( CHF_ABORT_COND_STACK_OVF );
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
ChfAbort(CHF_ABORT_COND_STACK_OVF);
|
ChfChar def_message[ CHF_DEF_MESSAGE_LENGTH ];
|
||||||
}
|
ChfChar tmp_message[ CHF_TMP_MESSAGE_LENGTH ];
|
||||||
|
|
||||||
else
|
new_descriptor->module_id = module_id;
|
||||||
{
|
new_descriptor->condition_code = condition_code;
|
||||||
ChfChar def_message[CHF_DEF_MESSAGE_LENGTH];
|
new_descriptor->severity = severity;
|
||||||
ChfChar tmp_message[CHF_TMP_MESSAGE_LENGTH];
|
new_descriptor->line_number = line_number;
|
||||||
|
new_descriptor->file_name = file_name;
|
||||||
|
|
||||||
new_descriptor->module_id = module_id;
|
/* Generate the default message */
|
||||||
new_descriptor->condition_code = condition_code;
|
ChfSprintf( def_message, CHF_DEF_PARTIAL_MSG_FMT, condition_code );
|
||||||
new_descriptor->severity = severity;
|
|
||||||
new_descriptor->line_number = line_number;
|
|
||||||
new_descriptor->file_name = file_name;
|
|
||||||
|
|
||||||
/* Generate the default message */
|
/* Generate the partial message associated with the condition using a
|
||||||
ChfSprintf(def_message, CHF_DEF_PARTIAL_MSG_FMT, condition_code);
|
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
|
/* Copy the message into the condition descriptor */
|
||||||
temporary area
|
ChfStrncpy( new_descriptor->message, tmp_message, CHF_MAX_MESSAGE_LENGTH - 1 );
|
||||||
*/
|
new_descriptor->message[ CHF_MAX_MESSAGE_LENGTH - 1 ] = '\0';
|
||||||
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 */
|
/* Link the new descriptor with the current descriptor list, if it
|
||||||
ChfStrncpy(new_descriptor->message, tmp_message, CHF_MAX_MESSAGE_LENGTH-1);
|
isn't the first descriptor of the list
|
||||||
new_descriptor->message[CHF_MAX_MESSAGE_LENGTH-1] = '\0';
|
*/
|
||||||
|
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
|
chf_context.condition_sp++;
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <errno.h>
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#include <tchar.h>
|
# include <tchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
#include "ChfPriv.h"
|
#include "ChfPriv.h"
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : StructuredHelper
|
.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,
|
ChfPushHandler() when its 'new_handler' argument is CHF_NULL_HANDLER,
|
||||||
and performs the following functions:
|
and performs the following functions:
|
||||||
|
|
||||||
- if called during an ordinary signalling operation with a
|
- if called during an ordinary signalling operation with a
|
||||||
CHF_FATAL condition, it requests the action CHF_UNWIND_KEEP
|
CHF_FATAL condition, it requests the action CHF_UNWIND_KEEP
|
||||||
|
|
||||||
- if called when Chf is in any other state, or with a
|
- if called when Chf is in any other state, or with a
|
||||||
severity less than CHF_FATAL, it requests the action CHF_RESIGNAL
|
severity less than CHF_FATAL, it requests the action CHF_RESIGNAL
|
||||||
|
|
||||||
The structured condition handling helper currently makes no use of
|
The structured condition handling helper currently makes no use of
|
||||||
handler_context.
|
handler_context.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
action = StructuredHelper(desc, state, context);
|
action = StructuredHelper(desc, state, context);
|
||||||
.input :
|
.input :
|
||||||
const ChfDescriptor *desc, condition descriptor
|
const ChfDescriptor *desc, condition descriptor
|
||||||
const ChfState state, current CHF state
|
const ChfState state, current CHF state
|
||||||
.output :
|
.output :
|
||||||
ChfAction action, action requested by the handler
|
ChfAction action, action requested by the handler
|
||||||
.status_codes :
|
.status_codes :
|
||||||
none
|
none
|
||||||
.notes :
|
.notes :
|
||||||
2.1, 19-May-2000, creation
|
2.1, 19-May-2000, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
static ChfAction StructuredHelper(
|
static ChfAction StructuredHelper( const ChfDescriptor* desc, const ChfState state, ChfPointer handler_context )
|
||||||
const ChfDescriptor *desc,
|
|
||||||
const ChfState state,
|
|
||||||
ChfPointer handler_context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ChfAction action;
|
ChfAction action;
|
||||||
const ChfDescriptor *d;
|
const ChfDescriptor* d;
|
||||||
|
|
||||||
return((state == CHF_SIGNALING && ChfGetSeverity(desc) == CHF_FATAL)
|
return ( ( state == CHF_SIGNALING && ChfGetSeverity( desc ) == CHF_FATAL ) ? CHF_UNWIND_KEEP : CHF_RESIGNAL );
|
||||||
? CHF_UNWIND_KEEP : CHF_RESIGNAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ChfPushHandler
|
.title : ChfPushHandler
|
||||||
|
@ -139,19 +132,19 @@ static ChfAction StructuredHelper(
|
||||||
conditions are CHF_FATAL.
|
conditions are CHF_FATAL.
|
||||||
|
|
||||||
NOTE: This function calls ChfAbort() with abort code CHF_ABORT_INIT if
|
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 :
|
.call :
|
||||||
ChfPushHandler(new_handler, unwind_context);
|
ChfPushHandler(new_handler, unwind_context);
|
||||||
.input :
|
.input :
|
||||||
ChfHandler new_handler, new condition handler
|
ChfHandler new_handler, new condition handler
|
||||||
void *unwind_context, handler unwind context pointer
|
void *unwind_context, handler unwind context pointer
|
||||||
ChfPointer handler_context, private handler context pointer
|
ChfPointer handler_context, private handler context pointer
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
(*) CHF_F_BAD_STATE, bad CHF state for requested operation
|
(*) CHF_F_BAD_STATE, bad CHF state for requested operation
|
||||||
(*) CHF_F_HDLR_STACK_FULL, the handler stack is full
|
(*) CHF_F_HDLR_STACK_FULL, the handler stack is full
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 13-May-1996, creation
|
1.1, 13-May-1996, creation
|
||||||
1.6, 15-Jan-1997, update:
|
1.6, 15-Jan-1997, update:
|
||||||
|
@ -162,44 +155,34 @@ static ChfAction StructuredHelper(
|
||||||
- added StructuredHelper handling
|
- added StructuredHelper handling
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void ChfPushHandler( /* Push a new handler into the stack */
|
void ChfPushHandler( /* Push a new handler into the stack */
|
||||||
ChfHandler new_handler,
|
ChfHandler new_handler, void* unwind_context, ChfPointer handler_context )
|
||||||
void *unwind_context,
|
|
||||||
ChfPointer handler_context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* Make sure that CHF has been correctly initialized and is idle */
|
/* 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_UNKNOWN )
|
||||||
|
ChfAbort( CHF_ABORT_INIT );
|
||||||
|
|
||||||
if(chf_context.state != CHF_IDLE)
|
if ( chf_context.state != CHF_IDLE ) {
|
||||||
{
|
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
||||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL
|
|
||||||
ChfEnd;
|
|
||||||
|
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the handler stack is full */
|
/* Check if the handler stack is full */
|
||||||
else if(chf_context.handler_sp - chf_context.handler_stack >=
|
else if ( chf_context.handler_sp - chf_context.handler_stack >= chf_context.handler_stack_size ) {
|
||||||
chf_context.handler_stack_size)
|
ChfCondition CHF_F_HDLR_STACK_FULL, CHF_FATAL ChfEnd;
|
||||||
{
|
|
||||||
ChfCondition CHF_F_HDLR_STACK_FULL, CHF_FATAL
|
|
||||||
ChfEnd;
|
|
||||||
|
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
chf_context.handler_sp->unwind_context = unwind_context;
|
||||||
chf_context.handler_sp->unwind_context = unwind_context;
|
chf_context.handler_sp->handler_context = handler_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->handler =
|
chf_context.handler_sp++;
|
||||||
((new_handler == CHF_NULL_HANDLER) ? StructuredHelper : new_handler);
|
}
|
||||||
chf_context.handler_sp++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ChfPopHandler
|
.title : ChfPopHandler
|
||||||
|
@ -215,17 +198,17 @@ void ChfPushHandler( /* Push a new handler into the stack */
|
||||||
conditions are CHF_FATAL.
|
conditions are CHF_FATAL.
|
||||||
|
|
||||||
NOTE: This function calls ChfAbort() with abort code CHF_ABORT_INIT if
|
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 :
|
.call :
|
||||||
ChfPopHandler();
|
ChfPopHandler();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
CHF_F_BAD_STATE, bad CHF state for requested operation
|
CHF_F_BAD_STATE, bad CHF state for requested operation
|
||||||
CHF_F_HDLR_STACK_FULL, the handler stack is full
|
CHF_F_HDLR_STACK_FULL, the handler stack is full
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 13-May-1996, creation
|
1.1, 13-May-1996, creation
|
||||||
1.6, 15-Jan-1997, update:
|
1.6, 15-Jan-1997, update:
|
||||||
|
@ -234,31 +217,27 @@ void ChfPushHandler( /* Push a new handler into the stack */
|
||||||
- improved documentation
|
- improved documentation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void ChfPopHandler( /* Pop a handler */
|
void ChfPopHandler( /* Pop a handler */
|
||||||
void
|
void )
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* Make sure that CHF has been correctly initialized and is idle */
|
/* 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_UNKNOWN )
|
||||||
|
ChfAbort( CHF_ABORT_INIT );
|
||||||
|
|
||||||
if(chf_context.state != CHF_IDLE)
|
if ( chf_context.state != CHF_IDLE ) {
|
||||||
{
|
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
||||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL
|
|
||||||
ChfEnd;
|
|
||||||
|
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the handler stack is empty */
|
/* Check if the handler stack is empty */
|
||||||
else if(chf_context.handler_sp == chf_context.handler_stack)
|
else if ( chf_context.handler_sp == chf_context.handler_stack ) {
|
||||||
{
|
ChfCondition CHF_F_HDLR_STACK_EMPTY, CHF_FATAL ChfEnd;
|
||||||
ChfCondition CHF_F_HDLR_STACK_EMPTY, CHF_FATAL
|
|
||||||
ChfEnd;
|
|
||||||
|
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Discard the topmost condition handler */
|
/* Discard the topmost condition handler */
|
||||||
else
|
else
|
||||||
--chf_context.handler_sp;
|
--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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <errno.h>
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#include <tchar.h>
|
# include <tchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
#include "ChfPriv.h"
|
#include "ChfPriv.h"
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Global and static variables
|
Global and static variables
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
@ -82,14 +81,13 @@ ChfContext _chf_context;
|
||||||
|
|
||||||
/* Message separator and severity names for ChfBuildMessage() */
|
/* Message separator and severity names for ChfBuildMessage() */
|
||||||
static const ChfChar separator[] = CHF_MESSAGE_SEPARATOR;
|
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
|
Multithreading support
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#include <pthread.h>
|
# include <pthread.h>
|
||||||
|
|
||||||
/* Mutex to access chf_context during initialization and exit;
|
/* Mutex to access chf_context during initialization and exit;
|
||||||
mutex to puts condition messages on stderr (DefaultHandler)
|
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
|
/* This function is called to destroy a Chf context when the owning
|
||||||
thread terminated.
|
thread terminated.
|
||||||
*/
|
*/
|
||||||
static void DestroyContext(void *context)
|
static void DestroyContext( void* context )
|
||||||
{
|
{
|
||||||
free(((ChfContext *)context)->message_buffer);
|
free( ( ( ChfContext* )context )->message_buffer );
|
||||||
free(((ChfContext *)context)->handler_stack);
|
free( ( ( ChfContext* )context )->handler_stack );
|
||||||
free(((ChfContext *)context)->condition_stack);
|
free( ( ( ChfContext* )context )->condition_stack );
|
||||||
free(context);
|
free( context );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Private functions
|
Private functions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : DefaultHandler
|
.title : DefaultHandler
|
||||||
|
@ -128,21 +124,21 @@ static void DestroyContext(void *context)
|
||||||
pushed into the condition handler stack by ChfInit() and performs the
|
pushed into the condition handler stack by ChfInit() and performs the
|
||||||
following functions:
|
following functions:
|
||||||
|
|
||||||
- if called during an unwind, it returns immediately to the caller,
|
- if called during an unwind, it returns immediately to the caller,
|
||||||
requesting the action CHF_RESIGNAL, else
|
requesting the action CHF_RESIGNAL, else
|
||||||
|
|
||||||
- if the severity of the condition being signalled is greater than
|
- if the severity of the condition being signalled is greater than
|
||||||
CHF_SUCCESS, it prints the messages associated with the entire
|
CHF_SUCCESS, it prints the messages associated with the entire
|
||||||
condition group on stderr using the standard function
|
condition group on stderr using the standard function
|
||||||
ChfBuildMessage() to build the messages.
|
ChfBuildMessage() to build the messages.
|
||||||
|
|
||||||
- if the severity of the condition being signalled is less than
|
- if the severity of the condition being signalled is less than
|
||||||
CHF_FATAL, it returns to the caller requesting the action
|
CHF_FATAL, it returns to the caller requesting the action
|
||||||
CHF_CONTINUE, else
|
CHF_CONTINUE, else
|
||||||
|
|
||||||
- if the CHF_FATAL condition was NOT signalled during an unwind
|
- if the CHF_FATAL condition was NOT signalled during an unwind
|
||||||
operation, it returns to the caller requesting the action
|
operation, it returns to the caller requesting the action
|
||||||
CHF_UNWIND, otherwise it requests the action CHF_RESIGNAL.
|
CHF_UNWIND, otherwise it requests the action CHF_RESIGNAL.
|
||||||
|
|
||||||
WIN32:
|
WIN32:
|
||||||
|
|
||||||
|
@ -151,14 +147,14 @@ static void DestroyContext(void *context)
|
||||||
anything
|
anything
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
action = DefaultHandler(desc, state, context);
|
action = DefaultHandler(desc, state, context);
|
||||||
.input :
|
.input :
|
||||||
const ChfDescriptor *desc, condition descriptor
|
const ChfDescriptor *desc, condition descriptor
|
||||||
const ChfState state, current CHF state
|
const ChfState state, current CHF state
|
||||||
.output :
|
.output :
|
||||||
ChfAction action, action requested by the handler
|
ChfAction action, action requested by the handler
|
||||||
.status_codes :
|
.status_codes :
|
||||||
none
|
none
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 16-May-1996, creation
|
1.1, 16-May-1996, creation
|
||||||
1.6, 15-Jan-1997, update:
|
1.6, 15-Jan-1997, update:
|
||||||
|
@ -170,69 +166,62 @@ static void DestroyContext(void *context)
|
||||||
- added Win32 support
|
- added Win32 support
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
static ChfAction DefaultHandler(
|
static ChfAction DefaultHandler( const ChfDescriptor* desc, const ChfState state, ChfPointer handler_context )
|
||||||
const ChfDescriptor *desc,
|
|
||||||
const ChfState state,
|
|
||||||
ChfPointer handler_context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ChfAction action;
|
ChfAction action;
|
||||||
const ChfDescriptor *d;
|
const ChfDescriptor* d;
|
||||||
|
|
||||||
if(state == CHF_UNWINDING)
|
if ( state == CHF_UNWINDING )
|
||||||
/* If CHF is unwinding, do nothing */
|
/* If CHF is unwinding, do nothing */
|
||||||
action = CHF_RESIGNAL;
|
action = CHF_RESIGNAL;
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Print the condition messages, if necessary. The sequence of fputs()
|
||||||
/* Print the condition messages, if necessary. The sequence of fputs()
|
is done atomically if multithreading support is enabled.
|
||||||
is done atomically if multithreading support is enabled.
|
In Win32, the default handler does not print anything.
|
||||||
In Win32, the default handler does not print anything.
|
*/
|
||||||
*/
|
if ( ChfGetSeverity( desc ) > CHF_SUCCESS ) {
|
||||||
if(ChfGetSeverity(desc) > CHF_SUCCESS)
|
|
||||||
{
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
if(pthread_mutex_lock(&fputs_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
if ( pthread_mutex_lock( &fputs_mutex ) )
|
||||||
|
ChfAbort( CHF_ABORT_PTHREAD );
|
||||||
#endif
|
#endif
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
for(d = desc; d != CHF_NULL_DESCRIPTOR; d = ChfGetNextDescriptor(d))
|
for ( d = desc; d != CHF_NULL_DESCRIPTOR; d = ChfGetNextDescriptor( d ) )
|
||||||
fputs(ChfBuildMessage(d), stderr);
|
fputs( ChfBuildMessage( d ), stderr );
|
||||||
#endif
|
#endif
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
if(pthread_mutex_unlock(&fputs_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
if ( pthread_mutex_unlock( &fputs_mutex ) )
|
||||||
|
ChfAbort( CHF_ABORT_PTHREAD );
|
||||||
#endif
|
#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 */
|
/* Return the action code to the Chf handler dispatcher */
|
||||||
switch(ChfGetSeverity(desc))
|
return action;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : scopy
|
.title : scopy
|
||||||
|
@ -244,45 +233,38 @@ static ChfAction DefaultHandler(
|
||||||
The function returns a pointer to the NUL-terminator just written.
|
The function returns a pointer to the NUL-terminator just written.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
np = scopy(p, q, p_end);
|
np = scopy(p, q, p_end);
|
||||||
.input :
|
.input :
|
||||||
char *p, starting position for the write
|
char *p, starting position for the write
|
||||||
const char *q, pointer to the string to be copied
|
const char *q, pointer to the string to be copied
|
||||||
char *p_end, pointer to the end of the output area
|
char *p_end, pointer to the end of the output area
|
||||||
.output :
|
.output :
|
||||||
char *np, pointer to the NUL-terminator just written
|
char *np, pointer to the NUL-terminator just written
|
||||||
.status_codes :
|
.status_codes :
|
||||||
none
|
none
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 16-May-1996, creation
|
1.1, 16-May-1996, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
static ChfChar *scopy(
|
static ChfChar* scopy( ChfChar* p, const ChfChar* q, ChfChar* p_end )
|
||||||
ChfChar *p,
|
|
||||||
const ChfChar *q,
|
|
||||||
ChfChar *p_end
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
size_t q_len = ChfStrlen(q);
|
size_t q_len = ChfStrlen( q );
|
||||||
size_t p_avail = p_end - p;
|
size_t p_avail = p_end - p;
|
||||||
|
|
||||||
if(q_len < p_avail)
|
if ( q_len < p_avail ) {
|
||||||
{
|
ChfStrcpy( p, q );
|
||||||
ChfStrcpy(p, q);
|
p += q_len;
|
||||||
p += q_len;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
else if(p_avail > 1)
|
else if ( p_avail > 1 ) {
|
||||||
{
|
ChfStrncpy( p, q, p_avail - 2 );
|
||||||
ChfStrncpy(p, q, p_avail-2);
|
p[ p_avail - 1 ] = '\0';
|
||||||
p[p_avail-1] = '\0';
|
p = p_end;
|
||||||
p = p_end;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
@ -300,10 +282,10 @@ static ChfChar *scopy(
|
||||||
necessary, to retrieve the requested message.
|
necessary, to retrieve the requested message.
|
||||||
|
|
||||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_INIT
|
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
|
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:
|
WIN32:
|
||||||
|
|
||||||
|
@ -311,46 +293,42 @@ static ChfChar *scopy(
|
||||||
codes in CHF_ERRNO_SET is not performed
|
codes in CHF_ERRNO_SET is not performed
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
message = ChfGetMessage(module_id, condition_code,
|
message = ChfGetMessage(module_id, condition_code,
|
||||||
default_message);
|
default_message);
|
||||||
.input :
|
.input :
|
||||||
const int module_id, module identifier
|
const int module_id, module identifier
|
||||||
const int condition_code, condition code
|
const int condition_code, condition code
|
||||||
const char *default_message, default message
|
const char *default_message, default message
|
||||||
.output :
|
.output :
|
||||||
const char *message, pointer to the retrieved message
|
const char *message, pointer to the retrieved message
|
||||||
.status_codes :
|
.status_codes :
|
||||||
none
|
none
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 17-May-1996, creation
|
1.1, 17-May-1996, creation
|
||||||
2.2, 22-Jan-2001, update:
|
2.2, 22-Jan-2001, update:
|
||||||
- added Win32 support
|
- added Win32 support
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
const ChfChar *ChfGetMessage( /* Retrieve a condition message */
|
const ChfChar* ChfGetMessage( /* Retrieve a condition message */
|
||||||
const int module_id,
|
const int module_id, const int condition_code, const ChfChar* default_message )
|
||||||
const int condition_code,
|
|
||||||
const ChfChar *default_message
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
const ChfChar *message;
|
const ChfChar* message;
|
||||||
|
|
||||||
/* Check that CHF has been correctly initialized */
|
/* Check that CHF has been correctly initialized */
|
||||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
if ( chf_context.state == CHF_UNKNOWN )
|
||||||
|
ChfAbort( CHF_ABORT_INIT );
|
||||||
|
|
||||||
if((message = chf_context.mrs_get(chf_context.mrs_data,
|
if ( ( message = chf_context.mrs_get( chf_context.mrs_data, module_id, condition_code, default_message ) ) == default_message &&
|
||||||
module_id, condition_code, default_message)) == default_message &&
|
module_id == CHF_ERRNO_SET )
|
||||||
module_id == CHF_ERRNO_SET)
|
#ifdef _WIN32
|
||||||
# ifdef _WIN32
|
message = default_message;
|
||||||
message = default_message;
|
#else
|
||||||
# else
|
message = strerror( condition_code );
|
||||||
message = strerror(condition_code);
|
#endif
|
||||||
# endif
|
|
||||||
|
|
||||||
return(message);
|
return ( message );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ChfBuildMessage
|
.title : ChfBuildMessage
|
||||||
|
@ -361,10 +339,10 @@ const ChfChar *ChfGetMessage( /* Retrieve a condition message */
|
||||||
descriptor and returns a pointer to a string containing it.
|
descriptor and returns a pointer to a string containing it.
|
||||||
|
|
||||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_INIT
|
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
|
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:
|
WIN32:
|
||||||
|
|
||||||
|
@ -372,87 +350,81 @@ const ChfChar *ChfGetMessage( /* Retrieve a condition message */
|
||||||
included in the message
|
included in the message
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
msg = ChfBuildMessage(descriptor);
|
msg = ChfBuildMessage(descriptor);
|
||||||
.input :
|
.input :
|
||||||
const ChfDescriptor *descriptor, condition descriptor
|
const ChfDescriptor *descriptor, condition descriptor
|
||||||
.output :
|
.output :
|
||||||
char *msg, pointer to the message associated with 'descriptor'
|
char *msg, pointer to the message associated with 'descriptor'
|
||||||
.status_codes :
|
.status_codes :
|
||||||
none
|
none
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 16-May-1996, creation
|
1.1, 16-May-1996, creation
|
||||||
2.2, 22-Jan-2001, update:
|
2.2, 22-Jan-2001, update:
|
||||||
- added Win32 support
|
- added Win32 support
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
ChfChar *ChfBuildMessage( /* Build a condition message */
|
ChfChar* ChfBuildMessage( /* Build a condition message */
|
||||||
const ChfDescriptor *descriptor
|
const ChfDescriptor* descriptor )
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ChfChar *tmp_p;
|
ChfChar* tmp_p;
|
||||||
ChfChar *tmp_end;
|
ChfChar* tmp_end;
|
||||||
ChfChar def_message[CHF_DEF_MESSAGE_LENGTH];
|
ChfChar def_message[ CHF_DEF_MESSAGE_LENGTH ];
|
||||||
ChfSeverity severity;
|
ChfSeverity severity;
|
||||||
|
|
||||||
/* Check that CHF has been correctly initialized */
|
/* Check that CHF has been correctly initialized */
|
||||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
if ( chf_context.state == CHF_UNKNOWN )
|
||||||
|
ChfAbort( CHF_ABORT_INIT );
|
||||||
|
|
||||||
/* Set appropriate pointers to the start/end of the message buffer */
|
/* Set appropriate pointers to the start/end of the message buffer */
|
||||||
tmp_p = chf_context.message_buffer;
|
tmp_p = chf_context.message_buffer;
|
||||||
tmp_end = tmp_p + CHF_MAX_MESSAGE_LENGTH;
|
tmp_end = tmp_p + CHF_MAX_MESSAGE_LENGTH;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/* The message starts with "<app_name>: " if the condition is the first of
|
/* The message starts with "<app_name>: " if the condition is the first of
|
||||||
its condition group, with "\t" if not.
|
its condition group, with "\t" if not.
|
||||||
*/
|
*/
|
||||||
if(descriptor == chf_context.condition_sp-1)
|
if ( descriptor == chf_context.condition_sp - 1 ) {
|
||||||
{
|
tmp_p = scopy( tmp_p, chf_context.app_name, tmp_end );
|
||||||
tmp_p = scopy(tmp_p, chf_context.app_name, tmp_end);
|
tmp_p = scopy( tmp_p, separator, tmp_end );
|
||||||
tmp_p = scopy(tmp_p, separator, tmp_end);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else
|
||||||
tmp_p = scopy(tmp_p, ChfText("\t"), tmp_end);
|
tmp_p = scopy( tmp_p, ChfText( "\t" ), tmp_end );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The message continues with the module name */
|
/* The message continues with the module name */
|
||||||
ChfSprintf(def_message, CHF_DEF_MID_MSG_FMT, ChfGetModuleId(descriptor));
|
ChfSprintf( def_message, CHF_DEF_MID_MSG_FMT, ChfGetModuleId( descriptor ) );
|
||||||
|
|
||||||
tmp_p = scopy(tmp_p,
|
tmp_p = scopy( tmp_p, ChfGetMessage( CHF_MODULE_NAMES_SET, ChfGetModuleId( descriptor ), def_message ), tmp_end );
|
||||||
ChfGetMessage(CHF_MODULE_NAMES_SET, ChfGetModuleId(descriptor),
|
|
||||||
def_message), tmp_end);
|
|
||||||
|
|
||||||
/* Add also the extended information, if any */
|
/* Add also the extended information, if any */
|
||||||
if(ChfGetLineNumber(descriptor) != CHF_UNKNOWN_LINE_NUMBER)
|
if ( ChfGetLineNumber( descriptor ) != CHF_UNKNOWN_LINE_NUMBER ) {
|
||||||
{
|
tmp_p = scopy( tmp_p, ChfText( " " ), tmp_end );
|
||||||
tmp_p = scopy(tmp_p, ChfText(" "), tmp_end);
|
|
||||||
|
|
||||||
ChfSprintf(def_message, CHF_EXTENDED_INFO_FMT,
|
ChfSprintf( def_message, CHF_EXTENDED_INFO_FMT, ChfGetFileName( descriptor ), ChfGetLineNumber( descriptor ) );
|
||||||
ChfGetFileName(descriptor), ChfGetLineNumber(descriptor));
|
|
||||||
|
|
||||||
tmp_p = scopy(tmp_p, def_message, tmp_end);
|
tmp_p = scopy( tmp_p, def_message, tmp_end );
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_p = scopy(tmp_p, separator, tmp_end);
|
tmp_p = scopy( tmp_p, separator, tmp_end );
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/* Add the severity code of the message */
|
/* Add the severity code of the message */
|
||||||
tmp_p = scopy(tmp_p,
|
tmp_p = scopy( tmp_p,
|
||||||
((severity = ChfGetSeverity(descriptor)) < CHF_SUCCESS ||
|
( ( severity = ChfGetSeverity( descriptor ) ) < CHF_SUCCESS || severity > CHF_FATAL ) ? CHF_UNKNOWN_SEVERITY
|
||||||
severity > CHF_FATAL) ? CHF_UNKNOWN_SEVERITY : severity_name[severity],
|
: severity_name[ severity ],
|
||||||
tmp_end);
|
tmp_end );
|
||||||
|
|
||||||
tmp_p = scopy(tmp_p, separator, tmp_end);
|
tmp_p = scopy( tmp_p, separator, tmp_end );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The message ends with the partial message from the descriptor */
|
/* The message ends with the partial message from the descriptor */
|
||||||
tmp_p = scopy(tmp_p, ChfGetPartialMessage(descriptor), tmp_end);
|
tmp_p = scopy( tmp_p, ChfGetPartialMessage( descriptor ), tmp_end );
|
||||||
(void)scopy(tmp_p, CHF_MESSAGE_TERMINATOR, tmp_end);
|
( void )scopy( tmp_p, CHF_MESSAGE_TERMINATOR, tmp_end );
|
||||||
|
|
||||||
return chf_context.message_buffer;
|
return chf_context.message_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ChfInit
|
.title : ChfInit
|
||||||
|
@ -467,29 +439,29 @@ ChfChar *ChfBuildMessage( /* Build a condition message */
|
||||||
function.
|
function.
|
||||||
|
|
||||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_DUP_INIT
|
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
|
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_PTHREAD
|
||||||
if a pthread operation fails.
|
if a pthread operation fails.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
cc = ChfInit(app_name, options,
|
cc = ChfInit(app_name, options,
|
||||||
mrs_data, mrs_get, mrs_exit,
|
mrs_data, mrs_get, mrs_exit,
|
||||||
condition_stack_size, handler_stack_size,
|
condition_stack_size, handler_stack_size,
|
||||||
exit_code);
|
exit_code);
|
||||||
.input :
|
.input :
|
||||||
const char *app_name, Application's name
|
const char *app_name, Application's name
|
||||||
const ChfOptions options, Options
|
const ChfOptions options, Options
|
||||||
void *mrs_data, Message retrieval private data
|
void *mrs_data, Message retrieval private data
|
||||||
ChfMrsGet mrs_get, 'GetMessage' function
|
ChfMrsGet mrs_get, 'GetMessage' function
|
||||||
ChfMrsExit mrs_exit, 'Exit' function
|
ChfMrsExit mrs_exit, 'Exit' function
|
||||||
const int condition_stack_size, Size of the condition stack
|
const int condition_stack_size, Size of the condition stack
|
||||||
const int handler_stack_size, Size of the handler stack
|
const int handler_stack_size, Size of the handler stack
|
||||||
const int exit_code, Abnormal exit code
|
const int exit_code, Abnormal exit code
|
||||||
.output :
|
.output :
|
||||||
int cc, condition code
|
int cc, condition code
|
||||||
.status_codes :
|
.status_codes :
|
||||||
CHF_F_MALLOC, FATAL, dynamic memory allocation failed
|
CHF_F_MALLOC, FATAL, dynamic memory allocation failed
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 13-May-1996, creation
|
1.1, 13-May-1996, creation
|
||||||
1.6, 15-Jan-1997, update:
|
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.
|
- added Win32 support; a malloc() call was not portable.
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
int ChfInit( /* Generic initialization */
|
int ChfInit( /* Generic initialization */
|
||||||
const ChfChar *app_name, /* Application's name */
|
const ChfChar* app_name, /* Application's name */
|
||||||
const ChfOptions options, /* Options */
|
const ChfOptions options, /* Options */
|
||||||
void *mrs_data, /* Message retrieval private data */
|
void* mrs_data, /* Message retrieval private data */
|
||||||
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
||||||
ChfMrsExit mrs_exit, /* 'Exit' function */
|
ChfMrsExit mrs_exit, /* 'Exit' function */
|
||||||
const int condition_stack_size, /* Size of the condition stack */
|
const int condition_stack_size, /* Size of the condition stack */
|
||||||
const int handler_stack_size, /* Size of the handler stack */
|
const int handler_stack_size, /* Size of the handler stack */
|
||||||
const int exit_code /* Abnormal exit code */
|
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
|
#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
|
#else
|
||||||
/* Reentrant check; lock context_mutex first */
|
/* Reentrant check; lock context_mutex first */
|
||||||
if(pthread_mutex_lock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
if ( pthread_mutex_lock( &context_mutex ) )
|
||||||
if(_chf_context.state != CHF_UNKNOWN)
|
ChfAbort( CHF_ABORT_PTHREAD );
|
||||||
{
|
if ( _chf_context.state != CHF_UNKNOWN ) {
|
||||||
if(pthread_mutex_unlock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
if ( pthread_mutex_unlock( &context_mutex ) )
|
||||||
ChfAbort(CHF_ABORT_DUP_INIT);
|
ChfAbort( CHF_ABORT_PTHREAD );
|
||||||
}
|
ChfAbort( CHF_ABORT_DUP_INIT );
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _REENTRANT
|
#ifndef _REENTRANT
|
||||||
if((_chf_context.condition_stack =
|
if ( ( _chf_context.condition_stack = ( ChfDescriptor* )malloc( ( size_t )( condition_stack_size + 1 ) * sizeof( ChfDescriptor ) ) ) ==
|
||||||
(ChfDescriptor *)
|
CHF_NULL_DESCRIPTOR )
|
||||||
malloc((size_t)(condition_stack_size+1)*sizeof(ChfDescriptor))) ==
|
cc = CHF_F_MALLOC;
|
||||||
CHF_NULL_DESCRIPTOR)
|
|
||||||
cc = CHF_F_MALLOC;
|
|
||||||
|
|
||||||
else if((_chf_context.handler_stack =
|
else if ( ( _chf_context.handler_stack = ( ChfHandlerDescriptor* )malloc(
|
||||||
(ChfHandlerDescriptor *)
|
( size_t )handler_stack_size * sizeof( ChfHandlerDescriptor ) ) ) == ( ChfHandlerDescriptor* )NULL ) {
|
||||||
malloc((size_t)handler_stack_size*sizeof(ChfHandlerDescriptor))) ==
|
free( _chf_context.condition_stack );
|
||||||
(ChfHandlerDescriptor *)NULL)
|
cc = CHF_F_MALLOC;
|
||||||
{
|
}
|
||||||
free(_chf_context.condition_stack);
|
|
||||||
cc = CHF_F_MALLOC;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if((_chf_context.message_buffer =
|
else if ( ( _chf_context.message_buffer = ( ChfChar* )malloc( ( size_t )( CHF_MAX_MESSAGE_LENGTH ) * sizeof( ChfChar ) ) ) ==
|
||||||
(ChfChar *)malloc(
|
( ChfChar* )NULL ) {
|
||||||
(size_t)(CHF_MAX_MESSAGE_LENGTH) * sizeof(ChfChar))) == (ChfChar *)NULL)
|
free( _chf_context.condition_stack );
|
||||||
{
|
free( _chf_context.handler_stack );
|
||||||
free(_chf_context.condition_stack);
|
cc = CHF_F_MALLOC;
|
||||||
free(_chf_context.handler_stack);
|
}
|
||||||
cc = CHF_F_MALLOC;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else
|
||||||
#else
|
#else
|
||||||
/* Reentrant init: condition_stack, handler_stack, message_buffer
|
/* Reentrant init: condition_stack, handler_stack, message_buffer
|
||||||
are not needed in the master Chf context.
|
are not needed in the master Chf context.
|
||||||
Init the Chf data key instead.
|
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.
|
|
||||||
*/
|
*/
|
||||||
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
|
#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
|
#ifdef _REENTRANT
|
||||||
if(pthread_mutex_unlock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
if ( pthread_mutex_unlock( &context_mutex ) )
|
||||||
|
ChfAbort( CHF_ABORT_PTHREAD );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ChfExit
|
.title : ChfExit
|
||||||
|
@ -610,82 +576,82 @@ int ChfInit( /* Generic initialization */
|
||||||
the application using ChfAbort() with abort code CHF_ABORT_INIT.
|
the application using ChfAbort() with abort code CHF_ABORT_INIT.
|
||||||
|
|
||||||
NOTE: This function will call 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
|
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_PTHREAD
|
||||||
if a pthread operation fails.
|
if a pthread operation fails.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
ChfExit();
|
ChfExit();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
none
|
none
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 24-May-1996, creation
|
1.1, 24-May-1996, creation
|
||||||
2.1, 19-May-2000, update:
|
2.1, 19-May-2000, update:
|
||||||
- added multithreading support
|
- added multithreading support
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void ChfExit(
|
void ChfExit( void )
|
||||||
void
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* Check that CHF has been correctly initialized */
|
/* Check that CHF has been correctly initialized */
|
||||||
#ifndef _REENTRANT
|
#ifndef _REENTRANT
|
||||||
if(_chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
if ( _chf_context.state == CHF_UNKNOWN )
|
||||||
|
ChfAbort( CHF_ABORT_INIT );
|
||||||
#else
|
#else
|
||||||
/* Reentrant check; lock context_mutex first */
|
/* Reentrant check; lock context_mutex first */
|
||||||
if(pthread_mutex_lock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
if ( pthread_mutex_lock( &context_mutex ) )
|
||||||
if(_chf_context.state == CHF_UNKNOWN)
|
ChfAbort( CHF_ABORT_PTHREAD );
|
||||||
{
|
if ( _chf_context.state == CHF_UNKNOWN ) {
|
||||||
if(pthread_mutex_unlock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
if ( pthread_mutex_unlock( &context_mutex ) )
|
||||||
ChfAbort(CHF_ABORT_INIT);
|
ChfAbort( CHF_ABORT_PTHREAD );
|
||||||
}
|
ChfAbort( CHF_ABORT_INIT );
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Destroy the context associated with this thread now; this is necessary
|
/* Destroy the context associated with this thread now; this is necessary
|
||||||
to ensure that the context is actually destroyed when a single-threaded
|
to ensure that the context is actually destroyed when a single-threaded
|
||||||
application links with the multithreaded version of Chf: in this case,
|
application links with the multithreaded version of Chf: in this case,
|
||||||
pthread_exit() is called *after* ChfExit(), the Chf data key no longer
|
pthread_exit() is called *after* ChfExit(), the Chf data key no longer
|
||||||
exists when pthread_exit() is called and the destructor registered
|
exists when pthread_exit() is called and the destructor registered
|
||||||
with pthread_key_create() does not take place.
|
with pthread_key_create() does not take place.
|
||||||
The data pointer associated with the Chf data key is set to NULL to
|
The data pointer associated with the Chf data key is set to NULL to
|
||||||
avoid any subsequent reactivation of the destructor.
|
avoid any subsequent reactivation of the destructor.
|
||||||
*/
|
*/
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
DestroyContext(&chf_context);
|
DestroyContext( &chf_context );
|
||||||
if(pthread_setspecific(data_key, (void *)NULL))
|
if ( pthread_setspecific( data_key, ( void* )NULL ) ) {
|
||||||
{
|
( void )pthread_mutex_unlock( &context_mutex );
|
||||||
(void)pthread_mutex_unlock(&context_mutex);
|
ChfAbort( CHF_ABORT_PTHREAD );
|
||||||
ChfAbort(CHF_ABORT_PTHREAD);
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Shut down the message retrieval subsystem first */
|
/* Shut down the message retrieval subsystem first */
|
||||||
_chf_context.mrs_exit(_chf_context.mrs_data);
|
_chf_context.mrs_exit( _chf_context.mrs_data );
|
||||||
|
|
||||||
#ifndef _REENTRANT
|
#ifndef _REENTRANT
|
||||||
/* Free the dynamic memory previously allocated */
|
/* Free the dynamic memory previously allocated */
|
||||||
free(_chf_context.message_buffer);
|
free( _chf_context.message_buffer );
|
||||||
free(_chf_context.handler_stack);
|
free( _chf_context.handler_stack );
|
||||||
free(_chf_context.condition_stack);
|
free( _chf_context.condition_stack );
|
||||||
#else
|
#else
|
||||||
/* Destroy the Chf data key */
|
/* Destroy the Chf data key */
|
||||||
if(pthread_key_delete(data_key)) ChfAbort(CHF_ABORT_PTHREAD);
|
if ( pthread_key_delete( data_key ) )
|
||||||
|
ChfAbort( CHF_ABORT_PTHREAD );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Reset CHF state to prevent subsequent calls to ChfExit() itself */
|
/* Reset CHF state to prevent subsequent calls to ChfExit() itself */
|
||||||
_chf_context.state = CHF_UNKNOWN;
|
_chf_context.state = CHF_UNKNOWN;
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
if(pthread_mutex_unlock(&context_mutex)) ChfAbort(CHF_ABORT_PTHREAD);
|
if ( pthread_mutex_unlock( &context_mutex ) )
|
||||||
|
ChfAbort( CHF_ABORT_PTHREAD );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : _ChfGetContext
|
.title : _ChfGetContext
|
||||||
|
@ -701,80 +667,66 @@ void ChfExit(
|
||||||
successful call to ChfInit().
|
successful call to ChfInit().
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
context = _ChfGetContext(void);
|
context = _ChfGetContext(void);
|
||||||
.input :
|
.input :
|
||||||
.output :
|
.output :
|
||||||
ChfContext *context, per-thread Chf context
|
ChfContext *context, per-thread Chf context
|
||||||
.status_codes :
|
.status_codes :
|
||||||
none
|
none
|
||||||
.notes :
|
.notes :
|
||||||
2.1, 19-May-2000, creation
|
2.1, 19-May-2000, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
ChfContext *_ChfGetContext(
|
ChfContext* _ChfGetContext( void )
|
||||||
void
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ChfContext *context;
|
ChfContext* context;
|
||||||
|
|
||||||
#ifndef _REENTRANT
|
#ifndef _REENTRANT
|
||||||
/* This function is doomed to fail if _REENTRANT is not defined */
|
/* This function is doomed to fail if _REENTRANT is not defined */
|
||||||
ChfAbort(CHF_ABORT_GET_CONTEXT);
|
ChfAbort( CHF_ABORT_GET_CONTEXT );
|
||||||
return((ChfContext *)NULL);
|
return ( ( ChfContext* )NULL );
|
||||||
#else
|
#else
|
||||||
/* Get the thread-specific context pointer associated with the
|
/* Get the thread-specific context pointer associated with the
|
||||||
CHF data key */
|
CHF data key */
|
||||||
if((context = (ChfContext *)pthread_getspecific(data_key))
|
if ( ( context = ( ChfContext* )pthread_getspecific( data_key ) ) == ( ChfContext* )NULL ) {
|
||||||
== (ChfContext *)NULL)
|
/* No context pointer; prime a new one, cloning the master context */
|
||||||
{
|
if ( ( context = ( ChfContext* )malloc( sizeof( ChfContext ) ) ) == ( ChfContext* )NULL )
|
||||||
/* No context pointer; prime a new one, cloning the master context */
|
ChfAbort( CHF_ABORT_GET_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 */
|
/* Allocate per-thread stacks and message buffer */
|
||||||
if((context->condition_stack =
|
if ( ( context->condition_stack = ( ChfDescriptor* )malloc( ( size_t )( context->condition_stack_size + 1 ) *
|
||||||
(ChfDescriptor *)
|
sizeof( ChfDescriptor ) ) ) == CHF_NULL_DESCRIPTOR )
|
||||||
malloc((size_t)(context->condition_stack_size+1)
|
ChfAbort( CHF_ABORT_GET_CONTEXT );
|
||||||
*sizeof(ChfDescriptor))) == CHF_NULL_DESCRIPTOR)
|
|
||||||
ChfAbort(CHF_ABORT_GET_CONTEXT);
|
|
||||||
|
|
||||||
if((context->handler_stack =
|
if ( ( context->handler_stack = ( ChfHandlerDescriptor* )malloc(
|
||||||
(ChfHandlerDescriptor *)
|
( size_t )( context->handler_stack_size ) * sizeof( ChfHandlerDescriptor ) ) ) == ( ChfHandlerDescriptor* )NULL ) {
|
||||||
malloc((size_t)(context->handler_stack_size)
|
free( context->condition_stack );
|
||||||
*sizeof(ChfHandlerDescriptor))) == (ChfHandlerDescriptor *)NULL)
|
ChfAbort( CHF_ABORT_GET_CONTEXT );
|
||||||
{
|
}
|
||||||
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 =
|
return context;
|
||||||
(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;
|
|
||||||
#endif
|
#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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <errno.h>
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <locale.h>
|
# include <locale.h>
|
||||||
#include <nl_types.h>
|
# include <nl_types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#include <tchar.h>
|
# include <tchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
#include "ChfPriv.h"
|
#include "ChfPriv.h"
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Global and static variables
|
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
|
#ifndef _WIN32
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
nl_catd catalog; /* Message catalog descriptor */
|
||||||
nl_catd catalog; /* Message catalog descriptor */
|
} ChfMsgcatContext;
|
||||||
}
|
|
||||||
ChfMsgcatContext;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Private functions
|
Private functions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
static const char *GetMessage(
|
static const char* GetMessage( void* private_context, const int module_id, const int condition_code, const char* default_message )
|
||||||
void *private_context,
|
|
||||||
const int module_id,
|
|
||||||
const int condition_code,
|
|
||||||
const char *default_message
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return(catgets(((ChfMsgcatContext *)private_context)->catalog, module_id,
|
return ( catgets( ( ( ChfMsgcatContext* )private_context )->catalog, module_id, condition_code, default_message ) );
|
||||||
condition_code, default_message));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ExitMessage(
|
static void ExitMessage( void* private_context )
|
||||||
void *private_context
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
(void)catclose(((ChfMsgcatContext *)private_context)->catalog);
|
( void )catclose( ( ( ChfMsgcatContext* )private_context )->catalog );
|
||||||
free(private_context);
|
free( private_context );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
@ -115,7 +101,7 @@ static void ExitMessage(
|
||||||
other CHF initialization routines before using any other CHF function.
|
other CHF initialization routines before using any other CHF function.
|
||||||
|
|
||||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_DUP_INIT
|
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:
|
WIN32:
|
||||||
|
|
||||||
|
@ -123,79 +109,72 @@ static void ExitMessage(
|
||||||
always returns CHF_F_NOT_AVAILABLE
|
always returns CHF_F_NOT_AVAILABLE
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
cc = ChfMsgcatInit(app_name, options,
|
cc = ChfMsgcatInit(app_name, options,
|
||||||
msgcat_name,
|
msgcat_name,
|
||||||
condition_stack_size, handler_stack_size,
|
condition_stack_size, handler_stack_size,
|
||||||
exit_code);
|
exit_code);
|
||||||
.input :
|
.input :
|
||||||
const char *app_name, Application's name
|
const char *app_name, Application's name
|
||||||
const ChfOptions options, Options
|
const ChfOptions options, Options
|
||||||
const char *msgcat_name, Name of the message catalog
|
const char *msgcat_name, Name of the message catalog
|
||||||
const int condition_stack_size, Size of the condition stack
|
const int condition_stack_size, Size of the condition stack
|
||||||
const int handler_stack_size, Size of the handler stack
|
const int handler_stack_size, Size of the handler stack
|
||||||
const int exit_code, Abnormal exit code
|
const int exit_code, Abnormal exit code
|
||||||
.output :
|
.output :
|
||||||
int cc, condition code
|
int cc, condition code
|
||||||
.status_codes :
|
.status_codes :
|
||||||
CHF_F_SETLOCALE, setlocale() failed
|
CHF_F_SETLOCALE, setlocale() failed
|
||||||
CHF_F_CATOPEN, catopen() failed
|
CHF_F_CATOPEN, catopen() failed
|
||||||
CHF_F_MALLOC, FATAL, memory allocation failed
|
CHF_F_MALLOC, FATAL, memory allocation failed
|
||||||
CHF_F_NOT_AVAILABLE, FATAL, function not available
|
CHF_F_NOT_AVAILABLE, FATAL, function not available
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 17-May-1996, creation
|
1.1, 17-May-1996, creation
|
||||||
2.2, 22-Jan-2001, update:
|
2.2, 22-Jan-2001, update:
|
||||||
- added Win32 support
|
- added Win32 support
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
int ChfMsgcatInit( /* Initialization with msgcat subsystem */
|
int ChfMsgcatInit( /* Initialization with msgcat subsystem */
|
||||||
const ChfChar *app_name, /* Application's name */
|
const ChfChar* app_name, /* Application's name */
|
||||||
const ChfOptions options, /* Options */
|
const ChfOptions options, /* Options */
|
||||||
const ChfChar *msgcat_name, /* Name of the message catalog */
|
const ChfChar* msgcat_name, /* Name of the message catalog */
|
||||||
const int condition_stack_size, /* Size of the condition stack */
|
const int condition_stack_size, /* Size of the condition stack */
|
||||||
const int handler_stack_size, /* Size of the handler stack */
|
const int handler_stack_size, /* Size of the handler stack */
|
||||||
const int exit_code /* Abnormal exit code */
|
const int exit_code /* Abnormal exit code */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
/* This function always fails in _WIN32, because message catalogs
|
/* This function always fails in _WIN32, because message catalogs
|
||||||
are not supported.
|
are not supported.
|
||||||
*/
|
*/
|
||||||
return CHF_F_NOT_AVAILABLE;
|
return CHF_F_NOT_AVAILABLE;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
ChfMsgcatContext *private_context;
|
ChfMsgcatContext* private_context;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
if((private_context =
|
if ( ( private_context = ( ChfMsgcatContext* )malloc( sizeof( ChfMsgcatContext ) ) ) == ( ChfMsgcatContext* )NULL )
|
||||||
(ChfMsgcatContext *)malloc(sizeof(ChfMsgcatContext))) ==
|
cc = CHF_F_MALLOC;
|
||||||
(ChfMsgcatContext *)NULL)
|
|
||||||
cc = CHF_F_MALLOC;
|
|
||||||
|
|
||||||
else if(setlocale(LC_ALL, "") == (char *)NULL)
|
else if ( setlocale( LC_ALL, "" ) == ( char* )NULL ) {
|
||||||
{
|
free( private_context );
|
||||||
free(private_context);
|
cc = CHF_F_SETLOCALE;
|
||||||
cc = CHF_F_SETLOCALE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
else if((private_context->catalog = catopen(msgcat_name, 0)) ==
|
else if ( ( private_context->catalog = catopen( msgcat_name, 0 ) ) == ( nl_catd )( -1 ) ) {
|
||||||
(nl_catd)(-1))
|
free( private_context );
|
||||||
{
|
cc = CHF_F_CATOPEN;
|
||||||
free(private_context);
|
}
|
||||||
cc = CHF_F_CATOPEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if((cc = ChfInit(app_name, options, (void *)private_context,
|
else if ( ( cc = ChfInit( app_name, options, ( void* )private_context, GetMessage, ExitMessage, condition_stack_size,
|
||||||
GetMessage, ExitMessage, condition_stack_size, handler_stack_size,
|
handler_stack_size, exit_code ) ) != CHF_S_OK ) {
|
||||||
exit_code)) != CHF_S_OK)
|
( void )catclose( private_context->catalog );
|
||||||
{
|
free( private_context );
|
||||||
(void)catclose(private_context->catalog);
|
}
|
||||||
free(private_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else
|
||||||
cc = CHF_S_OK;
|
cc = CHF_S_OK;
|
||||||
|
|
||||||
return cc;
|
return cc;
|
||||||
|
|
||||||
#endif
|
#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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <errno.h>
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#include <tchar.h>
|
# include <tchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
#include "ChfPriv.h"
|
#include "ChfPriv.h"
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ChfSignal
|
.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.
|
handlers.
|
||||||
|
|
||||||
NOTE: This function uses the CHF function 'ChfAbort()' to
|
NOTE: This function uses the CHF function 'ChfAbort()' to
|
||||||
abort the application if either
|
abort the application if either
|
||||||
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
||||||
- the last handler on the handler stack has returned an invalid action
|
- the last handler on the handler stack has returned an invalid action
|
||||||
code (abort code CHF_ABORT_INVALID_ACTION)
|
code (abort code CHF_ABORT_INVALID_ACTION)
|
||||||
- one of the handlers has requested the CHF_UNWIND action while
|
- one of the handlers has requested the CHF_UNWIND action while
|
||||||
CHF was already unwinding (abort code CHF_ABORT_ALREADY_UNWINDING)
|
CHF was already unwinding (abort code CHF_ABORT_ALREADY_UNWINDING)
|
||||||
- a CHF_FATAL condition was signalled while CHF was unwinding
|
- a CHF_FATAL condition was signalled while CHF was unwinding
|
||||||
(abort code CHF_ABORT_FATAL_UNWINDING)
|
(abort code CHF_ABORT_FATAL_UNWINDING)
|
||||||
- all the handlers refused to handle a condition (abort code
|
- all the handlers refused to handle a condition (abort code
|
||||||
CHF_ABORT_IMPROPERLY_HANDLED)
|
CHF_ABORT_IMPROPERLY_HANDLED)
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
(*) CHF_F_COND_STACK_FULL, the condition stack is full
|
(*) CHF_F_COND_STACK_FULL, the condition stack is full
|
||||||
(*) CHF_F_INVALID_ACTION, invalid handler action (%d)
|
(*) CHF_F_INVALID_ACTION, invalid handler action (%d)
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 10-May-1996, creation
|
1.1, 10-May-1996, creation
|
||||||
1.6, 15-Jan-1997, update & bug fix:
|
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
|
- added support for structured condition handling
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void ChfSignal(
|
void ChfSignal( void )
|
||||||
void
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ChfState saved_state;
|
ChfState saved_state;
|
||||||
ChfDescriptor *saved_condition_base;
|
ChfDescriptor* saved_condition_base;
|
||||||
ChfDescriptor *current_condition;
|
ChfDescriptor* current_condition;
|
||||||
ChfHandlerDescriptor *saved_handler_sp;
|
ChfHandlerDescriptor* saved_handler_sp;
|
||||||
ChfHandlerDescriptor *handler_up;
|
ChfHandlerDescriptor* handler_up;
|
||||||
ChfHandlerDescriptor *unwind_handler;
|
ChfHandlerDescriptor* unwind_handler;
|
||||||
ChfAction handler_result;
|
ChfAction handler_result;
|
||||||
|
|
||||||
/* Check that CHF has been correctly initialized and save the current CHF
|
/* 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
|
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
|
CHF_UNWINDING change to CHF_SIGNAL_UNWINDING, otherwise remain in the
|
||||||
previous state (that must be CHF_SIGNALING)
|
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.
|
|
||||||
*/
|
*/
|
||||||
current_condition = chf_context.condition_sp-1;
|
if ( chf_context.state == CHF_UNKNOWN )
|
||||||
saved_condition_base = chf_context.condition_base;
|
ChfAbort( CHF_ABORT_INIT );
|
||||||
chf_context.condition_base = chf_context.condition_sp;
|
saved_state = chf_context.state;
|
||||||
|
|
||||||
/* Save the current condition handler pointer */
|
if ( chf_context.state == CHF_IDLE )
|
||||||
saved_handler_sp = chf_context.handler_sp;
|
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:
|
if ( chf_context.condition_sp > chf_context.condition_base ) {
|
||||||
- when the handler stack is empty, or
|
/* Save the base of the current condition group and then update it in
|
||||||
- when the current handler returns either CHF_CONTINUE or CHF_UNWIND
|
order to allow further generation of conditions inside the condition
|
||||||
*/
|
handlers that will be called soon.
|
||||||
handler_result = CHF_RESIGNAL;
|
*/
|
||||||
while(handler_result == CHF_RESIGNAL &&
|
current_condition = chf_context.condition_sp - 1;
|
||||||
chf_context.handler_sp > chf_context.handler_stack)
|
saved_condition_base = chf_context.condition_base;
|
||||||
{
|
chf_context.condition_base = chf_context.condition_sp;
|
||||||
chf_context.handler_sp--;
|
|
||||||
|
|
||||||
/* The current condition handler, described by chf_context.handler_sp,
|
/* Save the current condition handler pointer */
|
||||||
can recursively invoke ChfGenerate() and ChfSignal().
|
saved_handler_sp = chf_context.handler_sp;
|
||||||
|
|
||||||
ChfGenerate() will store the new condition group starting from
|
/* Call the condition handlers; the loop will exit either:
|
||||||
chf_context.condition_sp, that points to the first free slot
|
- when the handler stack is empty, or
|
||||||
of the condition stack. During the first generation, since
|
- when the current handler returns either CHF_CONTINUE or CHF_UNWIND
|
||||||
chf_context.condition_sp == chf_context.condition_base, the
|
*/
|
||||||
link pointer of the condition will be NULL and, therefore,
|
handler_result = CHF_RESIGNAL;
|
||||||
the condition will be the first of a new condition group.
|
while ( handler_result == CHF_RESIGNAL && chf_context.handler_sp > chf_context.handler_stack ) {
|
||||||
|
chf_context.handler_sp--;
|
||||||
|
|
||||||
ChfSignal() will signal the condition group described by the
|
/* The current condition handler, described by chf_context.handler_sp,
|
||||||
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);
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
can recursively invoke ChfGenerate() and ChfSignal().
|
can recursively invoke ChfGenerate() and ChfSignal().
|
||||||
|
|
||||||
ChfGenerate() will store the new condition group starting from
|
ChfGenerate() will store the new condition group starting from
|
||||||
chf_context.condition_sp, that points to the first free slot
|
chf_context.condition_sp, that points to the first free slot
|
||||||
of the condition stack. During the first generation, since
|
of the condition stack. During the first generation, since
|
||||||
chf_context.condition_sp == chf_context.condition_base, the
|
chf_context.condition_sp == chf_context.condition_base, the
|
||||||
link pointer of the condition will be NULL and, therefore,
|
link pointer of the condition will be NULL and, therefore,
|
||||||
the condition will be the first of a new condition group.
|
the condition will be the first of a new condition group.
|
||||||
|
|
||||||
ChfSignal() will generate the condition group described by the
|
ChfSignal() will signal the condition group described by the
|
||||||
stack block from chf_context.condition_base to
|
stack block from chf_context.condition_base to
|
||||||
chf_context.condition_sp-1, if it contains at least one
|
chf_context.condition_sp-1, if it contains at least one condition;
|
||||||
condition; it will call the handlers starting from
|
it will call the handlers starting from chf_context.handler_sp-1,
|
||||||
chf_context.handler_sp-1, that describes the handler
|
that describes the handler immediately preceding the current 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(
|
handler_result =
|
||||||
current_condition, chf_context.state,
|
chf_context.handler_sp->handler( current_condition, chf_context.state, chf_context.handler_sp->handler_context );
|
||||||
handler_up->handler_context);
|
|
||||||
|
|
||||||
/* When the CHF state is CHF_UNWINDING, any condition group
|
/* When the CHF state is CHF_SIGNALING, any condition group generated
|
||||||
generated but not yet signalled when the current handler
|
but not yet signalled when the current handler exits must be merged
|
||||||
returns must be discarded
|
with the condition group currently being signalled, in order to allow
|
||||||
*/
|
the condition handlers to add their own conditions to the condition
|
||||||
chf_context.condition_sp = chf_context.condition_base;
|
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
|
When the CHF state is CHF_UNWINDING, the condition group for
|
||||||
condition handlers. chf_context.handler_sp points to the
|
which the UNWIND has been requested is 'frozen', no further
|
||||||
handler that requested the unwind; that handler has been
|
modifications are allowed on it, and the condition group is simply
|
||||||
unwinded and its location is now the first free slot in the
|
discarded.
|
||||||
condition handler stack.
|
*/
|
||||||
*/
|
if ( chf_context.condition_sp > chf_context.condition_base ) {
|
||||||
unwind_handler = chf_context.handler_sp;
|
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)
|
/* Link together the condition groups */
|
||||||
{
|
chf_context.condition_base->next = current_condition;
|
||||||
/* Normal unwind:
|
current_condition = chf_context.condition_sp - 1;
|
||||||
restore the condition stack pointers, discarding all condition
|
chf_context.condition_base = chf_context.condition_sp;
|
||||||
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().
|
else
|
||||||
If the handler hasn't a valid unwind_context associated with it,
|
chf_context.condition_sp = chf_context.condition_base;
|
||||||
simply abort the application.
|
}
|
||||||
*/
|
|
||||||
chf_context.state = CHF_IDLE;
|
|
||||||
|
|
||||||
if(unwind_handler->unwind_context == CHF_NULL_CONTEXT)
|
/* The action CHF_CONTINUE is not allowed if the current condition
|
||||||
ChfAbort(CHF_ABORT_SILENT);
|
severity is CHF_FATAL; it's automatically changed to CHF_RESIGNAL
|
||||||
else
|
*/
|
||||||
ChfSiglongjmp(unwind_handler->unwind_context, 1);
|
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:
|
/* Discard the current condition group */
|
||||||
{
|
chf_context.condition_base = chf_context.condition_sp = saved_condition_base;
|
||||||
ChfAbort(
|
|
||||||
(chf_context.state == CHF_SIGNALING) ?
|
|
||||||
CHF_ABORT_IMPROPERLY_HANDLED : CHF_ABORT_FATAL_UNWINDING);
|
|
||||||
|
|
||||||
break;
|
/* Restore che saved CHF state */
|
||||||
}
|
chf_context.state = saved_state;
|
||||||
|
|
||||||
default:
|
/* Continue from the instruction following the ChfSignal() */
|
||||||
{
|
break;
|
||||||
/* 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();
|
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
|
else {
|
||||||
ChfAbort(CHF_ABORT_INVALID_ACTION);
|
/* Change CHF state */
|
||||||
|
chf_context.state = CHF_UNWINDING;
|
||||||
|
|
||||||
break;
|
/* 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 */
|
/* Restore the old CHF state */
|
||||||
chf_context.state = saved_state;
|
chf_context.state = saved_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : ChfDiscard
|
.title : ChfDiscard
|
||||||
|
@ -373,30 +349,30 @@ void ChfSignal(
|
||||||
the condition stack is empty.
|
the condition stack is empty.
|
||||||
|
|
||||||
NOTE: This function uses the CHF function 'ChfAbort()' to
|
NOTE: This function uses the CHF function 'ChfAbort()' to
|
||||||
abort the application if either
|
abort the application if either
|
||||||
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
ChfDiscard();
|
ChfDiscard();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
none
|
none
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 17-May-1996, creation
|
1.1, 17-May-1996, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void ChfDiscard( /* Discard the current conditions */
|
void ChfDiscard( /* Discard the current conditions */
|
||||||
void
|
void )
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* Check that CHF has been correctly initialized */
|
/* Check that CHF has been correctly initialized */
|
||||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
if ( chf_context.state == CHF_UNKNOWN )
|
||||||
|
ChfAbort( CHF_ABORT_INIT );
|
||||||
|
|
||||||
/* Reset the current condition stack pointer to the current condition
|
/* Reset the current condition stack pointer to the current condition
|
||||||
stack base pointer
|
stack base pointer
|
||||||
*/
|
*/
|
||||||
chf_context.condition_sp = chf_context.condition_base;
|
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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <errno.h>
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#include <tchar.h>
|
# include <tchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
#include "ChfPriv.h"
|
#include "ChfPriv.h"
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Global and static variables
|
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
|
Private type definitions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
const ChfTable* table;
|
||||||
const ChfTable *table;
|
size_t size;
|
||||||
size_t size;
|
} ChfStaticContext;
|
||||||
}
|
|
||||||
ChfStaticContext;
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Private functions
|
Private functions
|
||||||
|
@ -69,88 +65,67 @@ typedef struct
|
||||||
/* Win32 does not have bsearch();
|
/* Win32 does not have bsearch();
|
||||||
provide a simple one from glibc here.
|
provide a simple one from glibc here.
|
||||||
*/
|
*/
|
||||||
static void *bsearch(
|
static void* bsearch( const void* key, const void* base, size_t nmemb, size_t size, int ( *compar )( const void*, const void* ) )
|
||||||
const void *key,
|
|
||||||
const void *base,
|
|
||||||
size_t nmemb,
|
|
||||||
size_t size,
|
|
||||||
int (*compar)(const void *, const void *)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
size_t l, u, idx;
|
size_t l, u, idx;
|
||||||
const void *p;
|
const void* p;
|
||||||
int comparison;
|
int comparison;
|
||||||
|
|
||||||
l = 0;
|
l = 0;
|
||||||
u = nmemb;
|
u = nmemb;
|
||||||
while (l < u)
|
while ( l < u ) {
|
||||||
{
|
idx = ( l + u ) / 2;
|
||||||
idx = (l + u) / 2;
|
p = ( void* )( ( ( const char* )base ) + ( idx * size ) );
|
||||||
p = (void *) (((const char *) base) + (idx * size));
|
comparison = ( *compar )( key, p );
|
||||||
comparison = (*compar) (key, p);
|
if ( comparison < 0 )
|
||||||
if (comparison < 0)
|
u = idx;
|
||||||
u = idx;
|
else if ( comparison > 0 )
|
||||||
else if (comparison > 0)
|
l = idx + 1;
|
||||||
l = idx + 1;
|
else
|
||||||
else
|
return ( void* )p;
|
||||||
return (void *) p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GT 1
|
#define GT 1
|
||||||
#define LT -1
|
#define LT -1
|
||||||
#define EQ 0
|
#define EQ 0
|
||||||
|
|
||||||
static int Search(
|
static int Search( const void* l, const void* r )
|
||||||
const void *l,
|
|
||||||
const void *r
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if(((ChfTable *)l)->module > ((ChfTable *)r)->module)
|
if ( ( ( ChfTable* )l )->module > ( ( ChfTable* )r )->module )
|
||||||
return(GT);
|
return ( GT );
|
||||||
|
|
||||||
else if(((ChfTable *)l)->module < ((ChfTable *)r)->module)
|
else if ( ( ( ChfTable* )l )->module < ( ( ChfTable* )r )->module )
|
||||||
return(LT);
|
return ( LT );
|
||||||
|
|
||||||
else if(((ChfTable *)l)->code > ((ChfTable *)r)->code)
|
else if ( ( ( ChfTable* )l )->code > ( ( ChfTable* )r )->code )
|
||||||
return(GT);
|
return ( GT );
|
||||||
|
|
||||||
else if(((ChfTable *)l)->code < ((ChfTable *)r)->code)
|
else if ( ( ( ChfTable* )l )->code < ( ( ChfTable* )r )->code )
|
||||||
return(LT);
|
return ( LT );
|
||||||
|
|
||||||
return(EQ);
|
return ( EQ );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ChfChar *StGetMessage(
|
static const ChfChar* StGetMessage( void* private_context, const int module_id, const int condition_code, const ChfChar* default_message )
|
||||||
void *private_context,
|
|
||||||
const int module_id,
|
|
||||||
const int condition_code,
|
|
||||||
const ChfChar *default_message
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ChfTable key;
|
ChfTable key;
|
||||||
ChfTable *res;
|
ChfTable* res;
|
||||||
|
|
||||||
key.module = module_id;
|
key.module = module_id;
|
||||||
key.code = condition_code;
|
key.code = condition_code;
|
||||||
|
|
||||||
if((res = bsearch(&key, ((ChfStaticContext *)private_context)->table,
|
if ( ( res = bsearch( &key, ( ( ChfStaticContext* )private_context )->table, ( ( ChfStaticContext* )private_context )->size,
|
||||||
((ChfStaticContext *)private_context)->size, sizeof(ChfTable), Search)) ==
|
sizeof( ChfTable ), Search ) ) == ( void* )NULL )
|
||||||
(void *)NULL)
|
return ( default_message );
|
||||||
return(default_message);
|
|
||||||
|
|
||||||
return(((ChfTable *)res)->msg_template);
|
return ( ( ( ChfTable* )res )->msg_template );
|
||||||
}
|
|
||||||
|
|
||||||
static void ExitMessage(
|
|
||||||
void *private_context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ExitMessage( void* private_context ) {}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
|
@ -170,58 +145,54 @@ static void ExitMessage(
|
||||||
other CHF initialization routines before using any other CHF function.
|
other CHF initialization routines before using any other CHF function.
|
||||||
|
|
||||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_DUP_INIT
|
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 :
|
.call :
|
||||||
cc = ChfStaticInit(app_name, options,
|
cc = ChfStaticInit(app_name, options,
|
||||||
table, table_size,
|
table, table_size,
|
||||||
condition_stack_size, handler_stack_size,
|
condition_stack_size, handler_stack_size,
|
||||||
exit_code);
|
exit_code);
|
||||||
.input :
|
.input :
|
||||||
const char *app_name, Application's name
|
const char *app_name, Application's name
|
||||||
const ChfOptions options, Options
|
const ChfOptions options, Options
|
||||||
const ChfTable *table, pointer to the static message table
|
const ChfTable *table, pointer to the static message table
|
||||||
const size_t table_size, size of the table (# of entries)
|
const size_t table_size, size of the table (# of entries)
|
||||||
const int condition_stack_size, Size of the condition stack
|
const int condition_stack_size, Size of the condition stack
|
||||||
const int handler_stack_size, Size of the handler stack
|
const int handler_stack_size, Size of the handler stack
|
||||||
const int exit_code, Abnormal exit code
|
const int exit_code, Abnormal exit code
|
||||||
.output :
|
.output :
|
||||||
int cc, condition code
|
int cc, condition code
|
||||||
.status_codes :
|
.status_codes :
|
||||||
CHF_F_MALLOC, FATAL, memory allocation failed
|
CHF_F_MALLOC, FATAL, memory allocation failed
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 27-May-1996, creation
|
1.1, 27-May-1996, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
int ChfStaticInit( /* Initialization with static message tables */
|
int ChfStaticInit( /* Initialization with static message tables */
|
||||||
const ChfChar *app_name, /* Application's name */
|
const ChfChar* app_name, /* Application's name */
|
||||||
const ChfOptions options, /* Options */
|
const ChfOptions options, /* Options */
|
||||||
const ChfTable *table, /* Static message table */
|
const ChfTable* table, /* Static message table */
|
||||||
const size_t table_size, /* Size of the message table */
|
const size_t table_size, /* Size of the message table */
|
||||||
const int condition_stack_size, /* Size of the condition stack */
|
const int condition_stack_size, /* Size of the condition stack */
|
||||||
const int handler_stack_size, /* Size of the handler stack */
|
const int handler_stack_size, /* Size of the handler stack */
|
||||||
const int exit_code /* Abnormal exit code */
|
const int exit_code /* Abnormal exit code */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ChfStaticContext *private_context;
|
ChfStaticContext* private_context;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
if((private_context =
|
if ( ( private_context = ( ChfStaticContext* )malloc( sizeof( ChfStaticContext ) ) ) == ( ChfStaticContext* )NULL )
|
||||||
(ChfStaticContext *)malloc(sizeof(ChfStaticContext))) ==
|
cc = CHF_F_MALLOC;
|
||||||
(ChfStaticContext *)NULL)
|
|
||||||
cc = CHF_F_MALLOC;
|
|
||||||
|
|
||||||
else if((cc = ChfInit(app_name, options, (void *)private_context,
|
else if ( ( cc = ChfInit( app_name, options, ( void* )private_context, StGetMessage, ExitMessage, condition_stack_size,
|
||||||
StGetMessage, ExitMessage, condition_stack_size, handler_stack_size,
|
handler_stack_size, exit_code ) ) != CHF_S_OK )
|
||||||
exit_code)) != CHF_S_OK)
|
free( private_context );
|
||||||
free(private_context);
|
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
private_context->table = table;
|
||||||
private_context->table = table;
|
private_context->size = table_size;
|
||||||
private_context->size = table_size;
|
cc = CHF_S_OK;
|
||||||
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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <errno.h>
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#include <tchar.h>
|
# include <tchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
#include "ChfPriv.h"
|
#include "ChfPriv.h"
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
@ -65,26 +64,26 @@ 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
|
NOTE: During condition signalling, CHF creates a new, empty, condition group
|
||||||
immediately before starting the invocation sequence of the condition
|
immediately before starting the invocation sequence of the condition
|
||||||
handlers, as described in the documentation. Therefore
|
handlers, as described in the documentation. Therefore
|
||||||
ChfGetTopCondition(), if called from a condition handler, will return
|
ChfGetTopCondition(), if called from a condition handler, will return
|
||||||
a pointer to the top condition generated during the handling ONLY, and
|
a pointer to the top condition generated during the handling ONLY, and
|
||||||
NOT to the top condition of the condition group being signalled. The
|
NOT to the top condition of the condition group being signalled. The
|
||||||
latter pointer is directly available, as an argument, to the condition
|
latter pointer is directly available, as an argument, to the condition
|
||||||
handlers.
|
handlers.
|
||||||
|
|
||||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_INIT
|
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
|
NOTE: The returned pointer is no longer valid when any other CHF function
|
||||||
is called after ChfGetTopCondition().
|
is called after ChfGetTopCondition().
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = ChfGetTopCondition();
|
d = ChfGetTopCondition();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
const ChfDescriptor *d, condition descriptor
|
const ChfDescriptor *d, condition descriptor
|
||||||
.status_codes :
|
.status_codes :
|
||||||
|
|
||||||
.notes :
|
.notes :
|
||||||
|
@ -93,23 +92,22 @@ static char rcs_id[] = "$Id: chf_top.c,v 2.2 2001/01/25 14:09:21 cibrario Exp $"
|
||||||
- condition stack referenced incorrectly
|
- condition stack referenced incorrectly
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
const ChfDescriptor *ChfGetTopCondition( /* Retrieve top condition */
|
const ChfDescriptor* ChfGetTopCondition( /* Retrieve top condition */
|
||||||
void
|
void )
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ChfDescriptor *d;
|
ChfDescriptor* d;
|
||||||
|
|
||||||
/* Check that CHF has been correctly initialized */
|
/* Check that CHF has been correctly initialized */
|
||||||
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
|
if ( chf_context.state == CHF_UNKNOWN )
|
||||||
|
ChfAbort( CHF_ABORT_INIT );
|
||||||
|
|
||||||
if((d = chf_context.condition_sp) == chf_context.condition_base)
|
if ( ( d = chf_context.condition_sp ) == chf_context.condition_base ) {
|
||||||
{
|
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
||||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* The top element of the condition group is the element immediately
|
/* The top element of the condition group is the element immediately
|
||||||
below the stack pointer.
|
below the stack pointer.
|
||||||
*/
|
*/
|
||||||
return d-1;
|
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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <errno.h>
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#include <tchar.h>
|
# include <tchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
#include "ChfPriv.h"
|
#include "ChfPriv.h"
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Global and static variables
|
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
|
#ifdef _WIN32
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
HINSTANCE instance; /* App. instance handle */
|
||||||
HINSTANCE instance; /* App. instance handle */
|
ChfChar buffer[ CHF_MAX_MESSAGE_LENGTH ]; /* Temporary buffer */
|
||||||
ChfChar buffer[CHF_MAX_MESSAGE_LENGTH]; /* Temporary buffer */
|
} ChfWin32Context;
|
||||||
}
|
|
||||||
ChfWin32Context;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Private functions
|
Private functions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static const ChfChar *Win32GetMessage(
|
static const ChfChar* Win32GetMessage( void* private_context, const int module_id, const int condition_code,
|
||||||
void *private_context,
|
const ChfChar* default_message )
|
||||||
const int module_id,
|
|
||||||
const int condition_code,
|
|
||||||
const ChfChar *default_message
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if(!LoadString(
|
if ( !LoadString( ( ( ChfWin32Context* )private_context )->instance, module_id * 1000 + condition_code,
|
||||||
((ChfWin32Context *)private_context)->instance,
|
( ( ChfWin32Context* )private_context )->buffer, CHF_MAX_MESSAGE_LENGTH - 1 ) )
|
||||||
module_id*1000 + condition_code,
|
return default_message;
|
||||||
((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(
|
static void ExitMessage( void* private_context ) { free( private_context ); }
|
||||||
void *private_context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
free(private_context);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
@ -109,7 +92,7 @@ static void ExitMessage(
|
||||||
other CHF initialization routines before using any other CHF function.
|
other CHF initialization routines before using any other CHF function.
|
||||||
|
|
||||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_DUP_INIT
|
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:
|
WIN32:
|
||||||
|
|
||||||
|
@ -124,68 +107,63 @@ static void ExitMessage(
|
||||||
0 <= module_id <= 64
|
0 <= module_id <= 64
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
cc = ChfWin32Init(app_name, options,
|
cc = ChfWin32Init(app_name, options,
|
||||||
msgcat_name,
|
msgcat_name,
|
||||||
condition_stack_size, handler_stack_size,
|
condition_stack_size, handler_stack_size,
|
||||||
exit_code);
|
exit_code);
|
||||||
.input :
|
.input :
|
||||||
const ChfChar *app_name, Application's name
|
const ChfChar *app_name, Application's name
|
||||||
const ChfOptions options, Options
|
const ChfOptions options, Options
|
||||||
HINSTANCE instance, App. instance handle
|
HINSTANCE instance, App. instance handle
|
||||||
const int condition_stack_size, Size of the condition stack
|
const int condition_stack_size, Size of the condition stack
|
||||||
const int handler_stack_size, Size of the handler stack
|
const int handler_stack_size, Size of the handler stack
|
||||||
const int exit_code, Abnormal exit code
|
const int exit_code, Abnormal exit code
|
||||||
.output :
|
.output :
|
||||||
int cc, condition code
|
int cc, condition code
|
||||||
.status_codes :
|
.status_codes :
|
||||||
CHF_F_MALLOC, FATAL, memory allocation failed
|
CHF_F_MALLOC, FATAL, memory allocation failed
|
||||||
CHF_F_NOT_AVAILABLE, FATAL, function not available
|
CHF_F_NOT_AVAILABLE, FATAL, function not available
|
||||||
.notes :
|
.notes :
|
||||||
2.2, 19-Jan-2001, creation
|
2.2, 19-Jan-2001, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
int ChfWin32Init( /* Initialization within _WIN32 */
|
int ChfWin32Init( /* Initialization within _WIN32 */
|
||||||
const ChfChar *app_name, /* Application's name */
|
const ChfChar* app_name, /* Application's name */
|
||||||
const ChfOptions options, /* Options */
|
const ChfOptions options, /* Options */
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
void *instance, /* Fake arguments */
|
void* instance, /* Fake arguments */
|
||||||
#else
|
#else
|
||||||
HINSTANCE instance, /* App. instance handle */
|
HINSTANCE instance, /* App. instance handle */
|
||||||
#endif
|
#endif
|
||||||
const int condition_stack_size, /* Size of the condition stack */
|
const int condition_stack_size, /* Size of the condition stack */
|
||||||
const int handler_stack_size, /* Size of the handler stack */
|
const int handler_stack_size, /* Size of the handler stack */
|
||||||
const int exit_code /* Abnormal exit code */
|
const int exit_code /* Abnormal exit code */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/* This function is available only in Win32 */
|
/* This function is available only in Win32 */
|
||||||
return CHF_F_NOT_AVAILABLE;
|
return CHF_F_NOT_AVAILABLE;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
ChfWin32Context *private_context;
|
ChfWin32Context* private_context;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
if((private_context =
|
if ( ( private_context = ( ChfWin32Context* )malloc( sizeof( ChfWin32Context ) ) ) == ( ChfWin32Context* )NULL )
|
||||||
(ChfWin32Context *)malloc(sizeof(ChfWin32Context))) ==
|
cc = CHF_F_MALLOC;
|
||||||
(ChfWin32Context *)NULL)
|
|
||||||
cc = CHF_F_MALLOC;
|
|
||||||
|
|
||||||
else if((cc = ChfInit(app_name, options, (void *)private_context,
|
else if ( ( cc = ChfInit( app_name, options, ( void* )private_context, Win32GetMessage, ExitMessage, condition_stack_size,
|
||||||
Win32GetMessage, ExitMessage, condition_stack_size, handler_stack_size,
|
handler_stack_size, exit_code ) ) != CHF_S_OK ) {
|
||||||
exit_code)) != CHF_S_OK)
|
free( private_context );
|
||||||
{
|
}
|
||||||
free(private_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Save Win32 specific context items into private Chf context */
|
||||||
/* Save Win32 specific context items into private Chf context */
|
private_context->instance = instance;
|
||||||
private_context->instance = instance;
|
|
||||||
|
|
||||||
cc = CHF_S_OK;
|
cc = CHF_S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cc;
|
return cc;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
12
src/libChf/resource.h
Executable file → Normal file
12
src/libChf/resource.h
Executable file → Normal file
|
@ -6,10 +6,10 @@
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
# ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
# define _APS_NEXT_RESOURCE_VALUE 101
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
# define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
# define _APS_NEXT_CONTROL_VALUE 1000
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
# define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,64 +11,55 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CHF_MODULE_ID 255
|
#define CHF_MODULE_ID 255
|
||||||
#define CHF_EXTENDED_INFO
|
#define CHF_EXTENDED_INFO
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
|
|
||||||
|
int main( int argc, char* argv[] )
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
{
|
||||||
int st;
|
int st;
|
||||||
const char *msg;
|
const char* msg;
|
||||||
const ChfDescriptor *d, *e;
|
const ChfDescriptor *d, *e;
|
||||||
|
|
||||||
puts("test01");
|
puts( "test01" );
|
||||||
|
|
||||||
system("gencat test01.cat test01.msf");
|
system( "gencat test01.cat test01.msf" );
|
||||||
system("gencat test01.cat chf.msf");
|
system( "gencat test01.cat chf.msf" );
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat", 50, 10, 1))
|
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", 50, 10, 1 ) )
|
||||||
exit(st);
|
exit( st );
|
||||||
|
|
||||||
/* ChfGetMessage:
|
/* ChfGetMessage:
|
||||||
message (CHF_MODULE_ID, 1) exists, (CHF_MODULE_ID, 2) does not
|
message (CHF_MODULE_ID, 1) exists, (CHF_MODULE_ID, 2) does not
|
||||||
*/
|
*/
|
||||||
msg = ChfGetMessage(CHF_MODULE_ID, 1, "Default_1");
|
msg = ChfGetMessage( CHF_MODULE_ID, 1, "Default_1" );
|
||||||
if(strcmp(msg, "Set_255,Message_1")) exit(EXIT_FAILURE);
|
if ( strcmp( msg, "Set_255,Message_1" ) )
|
||||||
msg = ChfGetMessage(CHF_MODULE_ID, 2, "Default_2");
|
exit( EXIT_FAILURE );
|
||||||
if(strcmp(msg, "Default_2")) 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 */
|
/* Generate a condition and check descriptor; this is line 46 */
|
||||||
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
||||||
|
|
||||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||||
if(
|
exit( EXIT_FAILURE );
|
||||||
d->module_id != CHF_MODULE_ID
|
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 3 || d->severity != CHF_WARNING || d->line_number != 46 ||
|
||||||
|| d->condition_code != 3
|
strcmp( d->file_name, "test01.c" ) || strcmp( d->message, "Set_255,Arg_456,Message_3" ) || d->next != NULL )
|
||||||
|| d->severity != CHF_WARNING
|
exit( EXIT_FAILURE );
|
||||||
|| 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 */
|
/* Generate another condition and check; this is line 60 */
|
||||||
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
||||||
|
|
||||||
if((e = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
if ( ( e = ChfGetTopCondition() ) == NULL )
|
||||||
if(
|
exit( EXIT_FAILURE );
|
||||||
e->module_id != CHF_MODULE_ID
|
if ( e->module_id != CHF_MODULE_ID || e->condition_code != 4 || e->severity != CHF_INFO || e->line_number != 60 ||
|
||||||
|| e->condition_code != 4
|
strcmp( e->file_name, "test01.c" ) || strcmp( e->message, "Set_255,Arg_arg,Message_4" ) || e->next != d )
|
||||||
|| e->severity != CHF_INFO
|
exit( EXIT_FAILURE );
|
||||||
|| 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 */
|
/* Discard the previous condition group and create a new one */
|
||||||
ChfDiscard();
|
ChfDiscard();
|
||||||
|
@ -76,18 +67,13 @@ int main(int argc, char *argv[])
|
||||||
/* This is line 77 */
|
/* This is line 77 */
|
||||||
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||||
|
|
||||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||||
if(
|
exit( EXIT_FAILURE );
|
||||||
d->module_id != CHF_MODULE_ID
|
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 5 || d->severity != CHF_ERROR || d->line_number != 77 ||
|
||||||
|| d->condition_code != 5
|
strcmp( d->file_name, "test01.c" ) || strcmp( d->message, "Set_255,Arg_456-789,Message_5" ) || d->next != NULL )
|
||||||
|| d->severity != CHF_ERROR
|
exit( EXIT_FAILURE );
|
||||||
|| 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 */
|
/* Exit Chf */
|
||||||
ChfExit();
|
ChfExit();
|
||||||
exit(EXIT_SUCCESS);
|
exit( EXIT_SUCCESS );
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,54 +11,45 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CHF_MODULE_ID 255
|
#define CHF_MODULE_ID 255
|
||||||
#define CHF_EXTENDED_INFO
|
#define CHF_EXTENDED_INFO
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
|
|
||||||
|
void* task( void* arg )
|
||||||
void *task(void *arg)
|
|
||||||
{
|
{
|
||||||
const char *msg;
|
const char* msg;
|
||||||
const ChfDescriptor *d, *e;
|
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 */
|
/* message (CHF_MODULE_ID, 1) exists, (CHF_MODULE_ID, 2) does not */
|
||||||
msg = ChfGetMessage(CHF_MODULE_ID, 1, "Default_1");
|
msg = ChfGetMessage( CHF_MODULE_ID, 1, "Default_1" );
|
||||||
if(strcmp(msg, "Set_255,Message_1")) exit(EXIT_FAILURE);
|
if ( strcmp( msg, "Set_255,Message_1" ) )
|
||||||
msg = ChfGetMessage(CHF_MODULE_ID, 2, "Default_2");
|
exit( EXIT_FAILURE );
|
||||||
if(strcmp(msg, "Default_2")) 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 */
|
/* Generate a condition and check descriptor; this is line 36 */
|
||||||
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
||||||
|
|
||||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||||
if(
|
exit( EXIT_FAILURE );
|
||||||
d->module_id != CHF_MODULE_ID
|
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 3 || d->severity != CHF_WARNING || d->line_number != 36 ||
|
||||||
|| d->condition_code != 3
|
strcmp( d->file_name, "test02.c" ) || strcmp( d->message, "Set_255,Arg_456,Message_3" ) || d->next != NULL )
|
||||||
|| d->severity != CHF_WARNING
|
exit( EXIT_FAILURE );
|
||||||
|| 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 */
|
/* Generate another condition and check; this is line 50 */
|
||||||
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
||||||
|
|
||||||
if((e = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
if ( ( e = ChfGetTopCondition() ) == NULL )
|
||||||
if(
|
exit( EXIT_FAILURE );
|
||||||
e->module_id != CHF_MODULE_ID
|
if ( e->module_id != CHF_MODULE_ID || e->condition_code != 4 || e->severity != CHF_INFO || e->line_number != 50 ||
|
||||||
|| e->condition_code != 4
|
strcmp( e->file_name, "test02.c" ) || strcmp( e->message, "Set_255,Arg_arg,Message_4" ) || e->next != d )
|
||||||
|| e->severity != CHF_INFO
|
exit( EXIT_FAILURE );
|
||||||
|| 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 */
|
/* Discard the previous condition group and create a new one */
|
||||||
ChfDiscard();
|
ChfDiscard();
|
||||||
|
@ -66,56 +57,49 @@ void *task(void *arg)
|
||||||
/* This is line 67 */
|
/* This is line 67 */
|
||||||
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||||
|
|
||||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||||
if(
|
exit( EXIT_FAILURE );
|
||||||
d->module_id != CHF_MODULE_ID
|
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 5 || d->severity != CHF_ERROR || d->line_number != 67 ||
|
||||||
|| d->condition_code != 5
|
strcmp( d->file_name, "test02.c" ) || strcmp( d->message, "Set_255,Arg_456-789,Message_5" ) || d->next != NULL )
|
||||||
|| d->severity != CHF_ERROR
|
exit( EXIT_FAILURE );
|
||||||
|| 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 st;
|
||||||
int i;
|
int i;
|
||||||
void *ret;
|
void* ret;
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
pthread_t t[N_THREADS];
|
pthread_t t[ N_THREADS ];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
puts("test02");
|
puts( "test02" );
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat", 50, 10, 1))
|
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", 50, 10, 1 ) )
|
||||||
exit(st);
|
exit( st );
|
||||||
|
|
||||||
/* Create */
|
/* Create */
|
||||||
for(i=0; i<N_THREADS; i++)
|
for ( i = 0; i < N_THREADS; i++ )
|
||||||
if(st = pthread_create(&(t[i]), NULL, task, (void *)i))
|
if ( st = pthread_create( &( t[ i ] ), NULL, task, ( void* )i ) ) {
|
||||||
{
|
printf( "pthread_create: error %d", st );
|
||||||
printf("pthread_create: error %d", st);
|
exit( EXIT_FAILURE );
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Join */
|
/* Join */
|
||||||
for(i=0; i<N_THREADS; i++)
|
for ( i = 0; i < N_THREADS; i++ )
|
||||||
if(st = pthread_join(t[i], &ret))
|
if ( st = pthread_join( t[ i ], &ret ) ) {
|
||||||
{
|
printf( "pthread_join: error %d", st );
|
||||||
printf("pthread_join: error %d", st);
|
exit( EXIT_FAILURE );
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Exit Chf */
|
/* Exit Chf */
|
||||||
ChfExit();
|
ChfExit();
|
||||||
#endif
|
#endif
|
||||||
exit(EXIT_SUCCESS);
|
exit( EXIT_SUCCESS );
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,77 +14,74 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CHF_MODULE_ID 255
|
#define CHF_MODULE_ID 255
|
||||||
#define CHF_EXTENDED_INFO
|
#define CHF_EXTENDED_INFO
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
|
|
||||||
|
void* task( void* arg )
|
||||||
void *task(void *arg)
|
|
||||||
{
|
{
|
||||||
const char *msg;
|
const char* msg;
|
||||||
const ChfDescriptor *d, *e;
|
const ChfDescriptor *d, *e;
|
||||||
|
|
||||||
/* The sleep() is here to increase contention between threads */
|
/* 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 */
|
/* 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 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 7, CHF_INFO, ( int )arg ChfEnd;
|
||||||
|
|
||||||
/* The sleep() is here to increase contention between threads */
|
/* The sleep() is here to increase contention between threads */
|
||||||
sleep(1);
|
sleep( 1 );
|
||||||
ChfSignal();
|
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 st;
|
||||||
int i;
|
int i;
|
||||||
void *ret;
|
void* ret;
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
pthread_t t[N_THREADS];
|
pthread_t t[ N_THREADS ];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
puts("test03");
|
puts( "test03" );
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat", 50, 10, 1))
|
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", 50, 10, 1 ) )
|
||||||
exit(st);
|
exit( st );
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
/* Create */
|
/* Create */
|
||||||
for(i=0; i<N_THREADS; i++)
|
for ( i = 0; i < N_THREADS; i++ )
|
||||||
if(pthread_create(&(t[i]), NULL, task, (void *)i))
|
if ( pthread_create( &( t[ i ] ), NULL, task, ( void* )i ) ) {
|
||||||
{
|
perror( "pthread_create" );
|
||||||
perror("pthread_create");
|
exit( EXIT_FAILURE );
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Join */
|
/* Join */
|
||||||
for(i=0; i<N_THREADS; i++)
|
for ( i = 0; i < N_THREADS; i++ )
|
||||||
if(pthread_join(t[i], &ret))
|
if ( pthread_join( t[ i ], &ret ) ) {
|
||||||
{
|
perror( "pthread_join" );
|
||||||
perror("pthread_join");
|
exit( EXIT_FAILURE );
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
task((void *)0);
|
task( ( void* )0 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Exit Chf */
|
/* Exit Chf */
|
||||||
ChfExit();
|
ChfExit();
|
||||||
exit(EXIT_SUCCESS);
|
exit( EXIT_SUCCESS );
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,193 +14,161 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CHF_MODULE_ID 255
|
#define CHF_MODULE_ID 255
|
||||||
#define CHF_EXTENDED_INFO
|
#define CHF_EXTENDED_INFO
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
|
|
||||||
struct tdata_s
|
struct tdata_s {
|
||||||
{
|
|
||||||
const ChfDescriptor *d, *e;
|
const ChfDescriptor *d, *e;
|
||||||
int phase;
|
int phase;
|
||||||
};
|
};
|
||||||
|
|
||||||
ChfAction h1(
|
ChfAction h1( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||||
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;
|
ChfAction action;
|
||||||
|
|
||||||
if(c != tdata_p->e ||
|
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d ) {
|
||||||
ChfGetNextDescriptor(c) != tdata_p->d)
|
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||||
{
|
action = CHF_RESIGNAL;
|
||||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
|
||||||
action = CHF_RESIGNAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
action = CHF_CONTINUE;
|
action = CHF_CONTINUE;
|
||||||
|
|
||||||
return action;
|
return action;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChfAction h2(
|
ChfAction h2( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||||
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;
|
ChfAction action;
|
||||||
|
|
||||||
switch(s)
|
switch ( s ) {
|
||||||
{
|
case CHF_SIGNALING:
|
||||||
case CHF_SIGNALING:
|
{
|
||||||
{
|
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d || ( tdata_p->phase != 2 && tdata_p->phase != 4 ) ) {
|
||||||
if(c != tdata_p->e
|
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||||
|| ChfGetNextDescriptor(c) != tdata_p->d
|
action = CHF_RESIGNAL;
|
||||||
|| (tdata_p->phase != 2 && tdata_p->phase != 4))
|
}
|
||||||
{
|
|
||||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
|
||||||
action = CHF_RESIGNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
action = ( ChfGetConditionCode( c ) != 8 ? CHF_CONTINUE : CHF_UNWIND );
|
||||||
action = (ChfGetConditionCode(c) != 8 ? CHF_CONTINUE : CHF_UNWIND);
|
}
|
||||||
}
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case CHF_UNWINDING:
|
||||||
case CHF_UNWINDING:
|
{
|
||||||
{
|
if ( tdata_p->phase != 4 )
|
||||||
if(tdata_p->phase != 4) exit(EXIT_FAILURE);
|
exit( EXIT_FAILURE );
|
||||||
tdata_p->phase = 5;
|
tdata_p->phase = 5;
|
||||||
action = CHF_CONTINUE;
|
action = CHF_CONTINUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
exit(EXIT_FAILURE);
|
exit( EXIT_FAILURE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChfAction h3(
|
ChfAction h3( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||||
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;
|
ChfAction action;
|
||||||
|
|
||||||
/* This handler must be invoked only during the first signal */
|
/* 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)
|
switch ( s ) {
|
||||||
{
|
case CHF_SIGNALING:
|
||||||
case CHF_SIGNALING:
|
{
|
||||||
{
|
if ( ChfGetConditionCode( c ) != 9 || ChfGetNextDescriptor( c ) != NULL ) {
|
||||||
if(ChfGetConditionCode(c) != 9 ||
|
exit( EXIT_FAILURE );
|
||||||
ChfGetNextDescriptor(c) != NULL)
|
}
|
||||||
{
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
tdata_p->phase = 4;
|
||||||
tdata_p->phase = 4;
|
action = CHF_CONTINUE;
|
||||||
action = CHF_CONTINUE;
|
}
|
||||||
}
|
break;
|
||||||
break;
|
}
|
||||||
}
|
default:
|
||||||
default:
|
{
|
||||||
{
|
exit( EXIT_FAILURE );
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChfAction h4(
|
ChfAction h4( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||||
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;
|
ChfAction action;
|
||||||
|
|
||||||
/* This handler must be invoked only during the first signal */
|
/* 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)
|
switch ( s ) {
|
||||||
{
|
case CHF_SIGNALING:
|
||||||
case CHF_SIGNALING:
|
{
|
||||||
{
|
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d ) {
|
||||||
if(c != tdata_p->e
|
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||||
|| ChfGetNextDescriptor(c) != tdata_p->d)
|
action = CHF_RESIGNAL;
|
||||||
{
|
}
|
||||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
|
||||||
action = CHF_RESIGNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* This generates a new group and signals it */
|
||||||
/* This generates a new group and signals it */
|
tdata_p->phase = 3;
|
||||||
tdata_p->phase = 3;
|
ChfCondition 9, CHF_INFO ChfEnd;
|
||||||
ChfCondition 9, CHF_INFO ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
|
|
||||||
if(tdata_p->phase != 4) exit(EXIT_FAILURE);
|
if ( tdata_p->phase != 4 )
|
||||||
tdata_p->phase = 5;
|
exit( EXIT_FAILURE );
|
||||||
|
tdata_p->phase = 5;
|
||||||
|
|
||||||
if(c != tdata_p->e
|
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d ) {
|
||||||
|| ChfGetNextDescriptor(c) != tdata_p->d)
|
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||||
{
|
action = CHF_RESIGNAL;
|
||||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
} else
|
||||||
action = CHF_RESIGNAL;
|
action = CHF_CONTINUE;
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
action = CHF_CONTINUE;
|
}
|
||||||
}
|
default:
|
||||||
break;
|
{
|
||||||
}
|
exit( EXIT_FAILURE );
|
||||||
default:
|
}
|
||||||
{
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *task(void *arg)
|
void* task( void* arg )
|
||||||
{
|
{
|
||||||
volatile struct tdata_s tdata;
|
volatile struct tdata_s tdata;
|
||||||
|
|
||||||
/* The sleep() is here to increase contention between threads */
|
/* 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 */
|
/* Push the handler */
|
||||||
ChfPushHandler(h1, NULL, (ChfPointer)(&tdata));
|
ChfPushHandler( h1, NULL, ( ChfPointer )( &tdata ) );
|
||||||
|
|
||||||
/* Generate a condition group and signal it */
|
/* Generate a condition group and signal it */
|
||||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||||
tdata.d = ChfGetTopCondition();
|
tdata.d = ChfGetTopCondition();
|
||||||
ChfCondition 7, CHF_INFO, (int)arg ChfEnd;
|
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||||
tdata.e = ChfGetTopCondition();
|
tdata.e = ChfGetTopCondition();
|
||||||
|
|
||||||
/* The sleep() is here to increase contention between threads */
|
/* The sleep() is here to increase contention between threads */
|
||||||
sleep(1);
|
sleep( 1 );
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
/* Pop the handler */
|
/* Pop the handler */
|
||||||
|
@ -210,122 +178,117 @@ void *task(void *arg)
|
||||||
and signal it; this checks that the handler has actually been
|
and signal it; this checks that the handler has actually been
|
||||||
removed.
|
removed.
|
||||||
*/
|
*/
|
||||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||||
tdata.d = NULL;
|
tdata.d = NULL;
|
||||||
ChfCondition 7, CHF_INFO, (int)arg ChfEnd;
|
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||||
tdata.e = NULL;
|
tdata.e = NULL;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
/* Conditional unwind test */
|
/* Conditional unwind test */
|
||||||
{
|
{
|
||||||
sigjmp_buf jb;
|
sigjmp_buf jb;
|
||||||
|
|
||||||
tdata.phase = 0;
|
tdata.phase = 0;
|
||||||
if(setjmp(jb) == 0)
|
if ( setjmp( jb ) == 0 ) {
|
||||||
{
|
ChfPushHandler( h2, jb, ( ChfPointer )( &tdata ) );
|
||||||
ChfPushHandler(h2, jb, (ChfPointer)(&tdata));
|
|
||||||
|
|
||||||
/* Generate a condition group and signal it */
|
/* Generate a condition group and signal it */
|
||||||
tdata.phase = 1;
|
tdata.phase = 1;
|
||||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||||
tdata.d = ChfGetTopCondition();
|
tdata.d = ChfGetTopCondition();
|
||||||
ChfCondition 7, CHF_INFO, (int)arg ChfEnd;
|
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||||
tdata.e = ChfGetTopCondition();
|
tdata.e = ChfGetTopCondition();
|
||||||
|
|
||||||
/* This does not trigger an unwind */
|
/* This does not trigger an unwind */
|
||||||
tdata.phase = 2;
|
tdata.phase = 2;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
tdata.phase = 3;
|
tdata.phase = 3;
|
||||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||||
tdata.d = ChfGetTopCondition();
|
tdata.d = ChfGetTopCondition();
|
||||||
ChfCondition 8, CHF_INFO, (int)arg ChfEnd;
|
ChfCondition 8, CHF_INFO, ( int )arg ChfEnd;
|
||||||
tdata.e = ChfGetTopCondition();
|
tdata.e = ChfGetTopCondition();
|
||||||
|
|
||||||
/* This MUST trigger an unwind */
|
/* This MUST trigger an unwind */
|
||||||
tdata.phase = 4;
|
tdata.phase = 4;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
exit(EXIT_FAILURE);
|
exit( EXIT_FAILURE );
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else
|
/* Unwind */
|
||||||
{
|
if ( tdata.phase != 5 )
|
||||||
/* Unwind */
|
exit( EXIT_FAILURE );
|
||||||
if(tdata.phase != 5)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
ChfPopHandler();
|
ChfPopHandler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Condition generation and signal while a signal is in progress;
|
/* Condition generation and signal while a signal is in progress;
|
||||||
this requires two handlers.
|
this requires two handlers.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
tdata.phase = 0;
|
tdata.phase = 0;
|
||||||
|
|
||||||
ChfPushHandler(h3, NULL, (ChfPointer)&tdata);
|
ChfPushHandler( h3, NULL, ( ChfPointer )&tdata );
|
||||||
ChfPushHandler(h4, NULL, (ChfPointer)&tdata);
|
ChfPushHandler( h4, NULL, ( ChfPointer )&tdata );
|
||||||
|
|
||||||
tdata.phase = 1;
|
tdata.phase = 1;
|
||||||
ChfCondition 6, CHF_INFO, (int)arg ChfEnd;
|
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||||
tdata.d = ChfGetTopCondition();
|
tdata.d = ChfGetTopCondition();
|
||||||
ChfCondition 7, CHF_INFO, (int)arg ChfEnd;
|
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||||
tdata.e = ChfGetTopCondition();
|
tdata.e = ChfGetTopCondition();
|
||||||
|
|
||||||
tdata.phase = 2;
|
tdata.phase = 2;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
if(tdata.phase != 5)
|
if ( tdata.phase != 5 )
|
||||||
exit(EXIT_FAILURE);
|
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 st;
|
||||||
int i;
|
int i;
|
||||||
void *ret;
|
void* ret;
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
pthread_t t[N_THREADS];
|
pthread_t t[ N_THREADS ];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
puts("test04");
|
puts( "test04" );
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat", 50, 10, 1))
|
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", 50, 10, 1 ) )
|
||||||
exit(st);
|
exit( st );
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
/* Create */
|
/* Create */
|
||||||
for(i=0; i<N_THREADS; i++)
|
for ( i = 0; i < N_THREADS; i++ )
|
||||||
if(pthread_create(&(t[i]), NULL, task, (void *)i))
|
if ( pthread_create( &( t[ i ] ), NULL, task, ( void* )i ) ) {
|
||||||
{
|
perror( "pthread_create" );
|
||||||
perror("pthread_create");
|
exit( EXIT_FAILURE );
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Join */
|
/* Join */
|
||||||
for(i=0; i<N_THREADS; i++)
|
for ( i = 0; i < N_THREADS; i++ )
|
||||||
if(pthread_join(t[i], &ret))
|
if ( pthread_join( t[ i ], &ret ) ) {
|
||||||
{
|
perror( "pthread_join" );
|
||||||
perror("pthread_join");
|
exit( EXIT_FAILURE );
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
task((void *)0);
|
task( ( void* )0 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Exit Chf */
|
/* Exit Chf */
|
||||||
ChfExit();
|
ChfExit();
|
||||||
exit(EXIT_SUCCESS);
|
exit( EXIT_SUCCESS );
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,63 +14,45 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CHF_MODULE_ID 255
|
#define CHF_MODULE_ID 255
|
||||||
#define CHF_EXTENDED_INFO
|
#define CHF_EXTENDED_INFO
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
|
|
||||||
#define H_STACK_SIZE 10
|
#define H_STACK_SIZE 10
|
||||||
#define C_STACK_SIZE 30
|
#define C_STACK_SIZE 30
|
||||||
|
|
||||||
/* Dummy handler; pushed only to verify that the handler stack overflow
|
/* Dummy handler; pushed only to verify that the handler stack overflow
|
||||||
checks are correct.
|
checks are correct.
|
||||||
*/
|
*/
|
||||||
ChfAction h1(
|
ChfAction h1( const ChfDescriptor* c, const ChfState s, ChfPointer p ) { return CHF_RESIGNAL; }
|
||||||
const ChfDescriptor *c,
|
|
||||||
const ChfState s,
|
|
||||||
ChfPointer p
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return CHF_RESIGNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Overflow check handler; it unwinds if the CHF_F_HDLR_STACK_FULL
|
/* Overflow check handler; it unwinds if the CHF_F_HDLR_STACK_FULL
|
||||||
condition is signalled exactly after H_STACK_SIZE-2 invocations
|
condition is signalled exactly after H_STACK_SIZE-2 invocations
|
||||||
of ChfPushHandler(), it resignals a modified condition if the
|
of ChfPushHandler(), it resignals a modified condition if the
|
||||||
condition is signalled too early
|
condition is signalled too early
|
||||||
*/
|
*/
|
||||||
ChfAction h2(
|
ChfAction h2( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||||
const ChfDescriptor *c,
|
|
||||||
const ChfState s,
|
|
||||||
ChfPointer p
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int push_count = *((int *)p);
|
int push_count = *( ( int* )p );
|
||||||
ChfAction action;
|
ChfAction action;
|
||||||
|
|
||||||
if(s == CHF_SIGNALING)
|
if ( s == CHF_SIGNALING ) {
|
||||||
{
|
if ( ChfGetModuleId( c ) == CHF_SET && ChfGetConditionCode( c ) == CHF_F_HDLR_STACK_FULL ) {
|
||||||
if(ChfGetModuleId(c) == CHF_SET
|
/* Handler stack is full; check correctness of the descriptor */
|
||||||
&& ChfGetConditionCode(c) == CHF_F_HDLR_STACK_FULL)
|
if ( push_count == H_STACK_SIZE - 2 && ChfGetNextDescriptor( c ) == NULL && ChfGetSeverity( c ) == CHF_FATAL )
|
||||||
{
|
action = CHF_UNWIND;
|
||||||
/* Handler stack is full; check correctness of the descriptor */
|
else {
|
||||||
if(push_count == H_STACK_SIZE-2
|
ChfCondition 11, CHF_FATAL, push_count, H_STACK_SIZE - 2 ChfEnd;
|
||||||
&& ChfGetNextDescriptor(c) == NULL
|
action = CHF_RESIGNAL;
|
||||||
&& ChfGetSeverity(c) == CHF_FATAL)
|
}
|
||||||
action = CHF_UNWIND;
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ChfCondition 11, CHF_FATAL, push_count, H_STACK_SIZE-2
|
|
||||||
ChfEnd;
|
|
||||||
action = CHF_RESIGNAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
action = CHF_RESIGNAL;
|
action = CHF_RESIGNAL;
|
||||||
|
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
@ -80,68 +62,55 @@ ChfAction h2(
|
||||||
of ChfCondition, it resignals a modified condition if the
|
of ChfCondition, it resignals a modified condition if the
|
||||||
condition is signalled too early
|
condition is signalled too early
|
||||||
*/
|
*/
|
||||||
ChfAction h3(
|
ChfAction h3( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||||
const ChfDescriptor *c,
|
|
||||||
const ChfState s,
|
|
||||||
ChfPointer p
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int push_count = *((int *)p);
|
int push_count = *( ( int* )p );
|
||||||
ChfAction action;
|
ChfAction action;
|
||||||
|
|
||||||
if(s == CHF_SIGNALING)
|
if ( s == CHF_SIGNALING ) {
|
||||||
{
|
if ( ChfGetModuleId( c ) == CHF_SET && ChfGetConditionCode( c ) == CHF_F_COND_STACK_FULL ) {
|
||||||
if(ChfGetModuleId(c) == CHF_SET
|
/* Handler stack is full; check correctness of the descriptor */
|
||||||
&& ChfGetConditionCode(c) == CHF_F_COND_STACK_FULL)
|
if ( push_count == C_STACK_SIZE && ChfGetNextDescriptor( c ) == NULL && ChfGetSeverity( c ) == CHF_FATAL )
|
||||||
{
|
action = CHF_UNWIND;
|
||||||
/* Handler stack is full; check correctness of the descriptor */
|
else {
|
||||||
if(push_count == C_STACK_SIZE
|
ChfCondition 12, CHF_FATAL, push_count, C_STACK_SIZE ChfEnd;
|
||||||
&& ChfGetNextDescriptor(c) == NULL
|
action = CHF_RESIGNAL;
|
||||||
&& ChfGetSeverity(c) == CHF_FATAL)
|
}
|
||||||
action = CHF_UNWIND;
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ChfCondition 12, CHF_FATAL, push_count, C_STACK_SIZE
|
|
||||||
ChfEnd;
|
|
||||||
action = CHF_RESIGNAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
action = CHF_RESIGNAL;
|
action = CHF_RESIGNAL;
|
||||||
|
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* task( void* arg )
|
||||||
void *task(void *arg)
|
|
||||||
{
|
{
|
||||||
int push_count = 0;
|
int push_count = 0;
|
||||||
sigjmp_buf jb;
|
sigjmp_buf jb;
|
||||||
|
|
||||||
/* The sleep() is here to increase contention between threads */
|
/* 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 */
|
/* Check handler stack overflow checks */
|
||||||
if(sigsetjmp(jb, 1) == 0)
|
if ( sigsetjmp( jb, 1 ) == 0 ) {
|
||||||
{
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Push the handler */
|
/* Push the handler */
|
||||||
ChfPushHandler(h2, jb, (ChfPointer)(&push_count));
|
ChfPushHandler( h2, jb, ( ChfPointer )( &push_count ) );
|
||||||
|
|
||||||
/* The sleep() is here to increase contention between threads */
|
/* The sleep() is here to increase contention between threads */
|
||||||
sleep(1);
|
sleep( 1 );
|
||||||
|
|
||||||
/* Push dummy handlers until an error should occur */
|
/* Push dummy handlers until an error should occur */
|
||||||
for(; push_count<H_STACK_SIZE-1; push_count++)
|
for ( ; push_count < H_STACK_SIZE - 1; push_count++ )
|
||||||
ChfPushHandler(h1, NULL, NULL);
|
ChfPushHandler( h1, NULL, NULL );
|
||||||
|
|
||||||
/* No error? Bad! */
|
/* No error? Bad! */
|
||||||
return (void *)EXIT_FAILURE;
|
return ( void* )EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flow control returns here if 'handler stack full' was signalled
|
/* Flow control returns here if 'handler stack full' was signalled
|
||||||
|
@ -149,22 +118,21 @@ void *task(void *arg)
|
||||||
Check condition stack overflow checks
|
Check condition stack overflow checks
|
||||||
*/
|
*/
|
||||||
push_count = 0;
|
push_count = 0;
|
||||||
if(sigsetjmp(jb, 1) == 0)
|
if ( sigsetjmp( jb, 1 ) == 0 ) {
|
||||||
{
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Push the handler */
|
/* Push the handler */
|
||||||
ChfPushHandler(h3, jb, (ChfPointer)(&push_count));
|
ChfPushHandler( h3, jb, ( ChfPointer )( &push_count ) );
|
||||||
|
|
||||||
/* The sleep() is here to increase contention between threads */
|
/* The sleep() is here to increase contention between threads */
|
||||||
sleep(1);
|
sleep( 1 );
|
||||||
|
|
||||||
/* Push dummy conditions until an error should occur */
|
/* Push dummy conditions until an error should occur */
|
||||||
for(; push_count<=C_STACK_SIZE; push_count++)
|
for ( ; push_count <= C_STACK_SIZE; push_count++ )
|
||||||
ChfCondition 1, CHF_INFO ChfEnd;
|
ChfCondition 1, CHF_INFO ChfEnd;
|
||||||
|
|
||||||
/* No error? Bad! */
|
/* No error? Bad! */
|
||||||
return (void *)EXIT_FAILURE;
|
return ( void* )EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flow control returns here if 'condition stack full' was signalled
|
/* 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.
|
conditions were left out in the previous check.
|
||||||
*/
|
*/
|
||||||
push_count = 0;
|
push_count = 0;
|
||||||
if(sigsetjmp(jb, 1) == 0)
|
if ( sigsetjmp( jb, 1 ) == 0 ) {
|
||||||
{
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Push the handler */
|
/* Push the handler */
|
||||||
ChfPushHandler(h3, jb, (ChfPointer)(&push_count));
|
ChfPushHandler( h3, jb, ( ChfPointer )( &push_count ) );
|
||||||
|
|
||||||
/* The sleep() is here to increase contention between threads */
|
/* The sleep() is here to increase contention between threads */
|
||||||
sleep(1);
|
sleep( 1 );
|
||||||
|
|
||||||
/* Push dummy conditions until an error should occur */
|
/* Push dummy conditions until an error should occur */
|
||||||
for(; push_count<=C_STACK_SIZE; push_count++)
|
for ( ; push_count <= C_STACK_SIZE; push_count++ )
|
||||||
ChfCondition 1, CHF_INFO ChfEnd;
|
ChfCondition 1, CHF_INFO ChfEnd;
|
||||||
|
|
||||||
/* No error? Bad! */
|
/* No error? Bad! */
|
||||||
return (void *)EXIT_FAILURE;
|
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 st;
|
||||||
int i;
|
int i;
|
||||||
void *ret;
|
void* ret;
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
pthread_t t[N_THREADS];
|
pthread_t t[ N_THREADS ];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
puts("test05");
|
puts( "test05" );
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat",
|
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", C_STACK_SIZE, H_STACK_SIZE, EXIT_FAILURE ) )
|
||||||
C_STACK_SIZE, H_STACK_SIZE, EXIT_FAILURE))
|
exit( st );
|
||||||
exit(st);
|
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
/* Create */
|
/* Create */
|
||||||
for(i=0; i<N_THREADS; i++)
|
for ( i = 0; i < N_THREADS; i++ )
|
||||||
if(pthread_create(&(t[i]), NULL, task, (void *)i))
|
if ( pthread_create( &( t[ i ] ), NULL, task, ( void* )i ) ) {
|
||||||
{
|
perror( "pthread_create" );
|
||||||
perror("pthread_create");
|
exit( EXIT_FAILURE );
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Join */
|
/* Join */
|
||||||
for(i=0; i<N_THREADS; i++)
|
for ( i = 0; i < N_THREADS; i++ ) {
|
||||||
{
|
if ( pthread_join( t[ i ], &ret ) ) {
|
||||||
if(pthread_join(t[i], &ret))
|
perror( "pthread_join" );
|
||||||
{
|
exit( EXIT_FAILURE );
|
||||||
perror("pthread_join");
|
} else if ( ( int )ret != EXIT_SUCCESS )
|
||||||
exit(EXIT_FAILURE);
|
exit( ( int )ret );
|
||||||
}
|
|
||||||
else if((int)ret != EXIT_SUCCESS)
|
|
||||||
exit((int)ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
st = EXIT_SUCCESS;
|
st = EXIT_SUCCESS;
|
||||||
#else
|
#else
|
||||||
st = (int)task((void *)0);
|
st = ( int )task( ( void* )0 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Exit Chf */
|
/* Exit Chf */
|
||||||
ChfExit();
|
ChfExit();
|
||||||
exit(st);
|
exit( st );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,125 +14,109 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CHF_MODULE_ID 255
|
#define CHF_MODULE_ID 255
|
||||||
#define CHF_EXTENDED_INFO
|
#define CHF_EXTENDED_INFO
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
|
|
||||||
#define H_STACK_SIZE 10
|
#define H_STACK_SIZE 10
|
||||||
#define C_STACK_SIZE 30
|
#define C_STACK_SIZE 30
|
||||||
|
|
||||||
|
void* task( void* arg )
|
||||||
void *task(void *arg)
|
|
||||||
{
|
{
|
||||||
volatile int phase = 0;
|
volatile int phase = 0;
|
||||||
|
|
||||||
ChfTry
|
ChfTry
|
||||||
{
|
{
|
||||||
phase = 1;
|
phase = 1;
|
||||||
ChfCondition 20, CHF_SUCCESS ChfEnd;
|
ChfCondition 20, CHF_SUCCESS ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
phase = 2;
|
phase = 2;
|
||||||
ChfCondition 20, CHF_INFO ChfEnd;
|
ChfCondition 20, CHF_INFO ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
phase = 3;
|
phase = 3;
|
||||||
ChfCondition 20, CHF_WARNING ChfEnd;
|
ChfCondition 20, CHF_WARNING ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
phase = 4;
|
phase = 4;
|
||||||
ChfCondition 20, CHF_ERROR ChfEnd;
|
ChfCondition 20, CHF_ERROR ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
phase = 5;
|
phase = 5;
|
||||||
ChfCondition 20, CHF_FATAL ChfEnd;
|
ChfCondition 20, CHF_FATAL ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
|
|
||||||
/* Should not be reached */
|
/* Should not be reached */
|
||||||
return (void *)EXIT_FAILURE;
|
return ( void* )EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
ChfCatch
|
ChfCatch
|
||||||
{
|
{
|
||||||
/* Catched an exception; check descriptor */
|
/* Catched an exception; check descriptor */
|
||||||
const ChfDescriptor *d = ChfGetTopCondition();
|
const ChfDescriptor* d = ChfGetTopCondition();
|
||||||
if(d == NULL
|
if ( d == NULL || ChfGetNextDescriptor( d ) != NULL || ChfGetModuleId( d ) != CHF_MODULE_ID || ChfGetConditionCode( d ) != 20 )
|
||||||
|| ChfGetNextDescriptor(d) != NULL
|
return ( void* )EXIT_FAILURE;
|
||||||
|| ChfGetModuleId(d) != CHF_MODULE_ID
|
}
|
||||||
|| ChfGetConditionCode(d) != 20)
|
|
||||||
return (void *)EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
ChfEndTry;
|
ChfEndTry;
|
||||||
|
|
||||||
/* Check that the condition stack actually is empty after catch */
|
/* Check that the condition stack actually is empty after catch */
|
||||||
ChfTry
|
ChfTry { const volatile ChfDescriptor* e = ChfGetTopCondition(); }
|
||||||
{
|
|
||||||
volatile const ChfDescriptor *e = ChfGetTopCondition();
|
|
||||||
}
|
|
||||||
ChfCatch
|
ChfCatch
|
||||||
{
|
{
|
||||||
const ChfDescriptor *d = ChfGetTopCondition();
|
const ChfDescriptor* d = ChfGetTopCondition();
|
||||||
if(d == NULL
|
if ( d == NULL || ChfGetNextDescriptor( d ) != NULL || ChfGetModuleId( d ) != CHF_SET ||
|
||||||
|| ChfGetNextDescriptor(d) != NULL
|
ChfGetConditionCode( d ) != CHF_F_BAD_STATE )
|
||||||
|| ChfGetModuleId(d) != CHF_SET
|
return ( void* )EXIT_FAILURE;
|
||||||
|| ChfGetConditionCode(d) != CHF_F_BAD_STATE)
|
}
|
||||||
return (void *)EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
ChfEndTry;
|
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 st;
|
||||||
int i;
|
int i;
|
||||||
void *ret;
|
void* ret;
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
pthread_t t[N_THREADS];
|
pthread_t t[ N_THREADS ];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
puts("test06");
|
puts( "test06" );
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
if(st = ChfMsgcatInit(argv[0], CHF_DEFAULT, "./test01.cat",
|
if ( st = ChfMsgcatInit( argv[ 0 ], CHF_DEFAULT, "./test01.cat", C_STACK_SIZE, H_STACK_SIZE, EXIT_FAILURE ) )
|
||||||
C_STACK_SIZE, H_STACK_SIZE, EXIT_FAILURE))
|
exit( st );
|
||||||
exit(st);
|
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
/* Create */
|
/* Create */
|
||||||
for(i=0; i<N_THREADS; i++)
|
for ( i = 0; i < N_THREADS; i++ )
|
||||||
if(pthread_create(&(t[i]), NULL, task, (void *)i))
|
if ( pthread_create( &( t[ i ] ), NULL, task, ( void* )i ) ) {
|
||||||
{
|
perror( "pthread_create" );
|
||||||
perror("pthread_create");
|
exit( EXIT_FAILURE );
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Join */
|
/* Join */
|
||||||
for(i=0; i<N_THREADS; i++)
|
for ( i = 0; i < N_THREADS; i++ ) {
|
||||||
{
|
if ( pthread_join( t[ i ], &ret ) ) {
|
||||||
if(pthread_join(t[i], &ret))
|
perror( "pthread_join" );
|
||||||
{
|
exit( EXIT_FAILURE );
|
||||||
perror("pthread_join");
|
} else if ( ( int )ret != EXIT_SUCCESS )
|
||||||
exit(EXIT_FAILURE);
|
exit( ( int )ret );
|
||||||
}
|
|
||||||
else if((int)ret != EXIT_SUCCESS)
|
|
||||||
exit((int)ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
st = EXIT_SUCCESS;
|
st = EXIT_SUCCESS;
|
||||||
#else
|
#else
|
||||||
st = (int)task((void *)0);
|
st = ( int )task( ( void* )0 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Exit Chf */
|
/* Exit Chf */
|
||||||
ChfExit();
|
ChfExit();
|
||||||
exit(st);
|
exit( st );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,64 +11,55 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CHF_MODULE_ID 255
|
#define CHF_MODULE_ID 255
|
||||||
#define CHF_EXTENDED_INFO
|
#define CHF_EXTENDED_INFO
|
||||||
#include "Chf.h"
|
#include "Chf.h"
|
||||||
|
|
||||||
extern ChfTable message_table[];
|
extern ChfTable message_table[];
|
||||||
extern size_t message_table_size;
|
extern size_t message_table_size;
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
int st;
|
int st;
|
||||||
const char *msg;
|
const char* msg;
|
||||||
const ChfDescriptor *d, *e;
|
const ChfDescriptor *d, *e;
|
||||||
|
|
||||||
puts("test07");
|
puts( "test07" );
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
if(st = ChfStaticInit(argv[0], CHF_DEFAULT,
|
if ( st = ChfStaticInit( argv[ 0 ], CHF_DEFAULT, message_table, message_table_size, 50, 10, 1 ) )
|
||||||
message_table, message_table_size, 50, 10, 1))
|
exit( st );
|
||||||
exit(st);
|
|
||||||
|
|
||||||
/* ChfGetMessage:
|
/* ChfGetMessage:
|
||||||
message (CHF_MODULE_ID, 1) exists, (CHF_MODULE_ID, 2) does not
|
message (CHF_MODULE_ID, 1) exists, (CHF_MODULE_ID, 2) does not
|
||||||
*/
|
*/
|
||||||
msg = ChfGetMessage(CHF_MODULE_ID, 1, "Default_1");
|
msg = ChfGetMessage( CHF_MODULE_ID, 1, "Default_1" );
|
||||||
if(strcmp(msg, "Set_255,Message_1")) exit(EXIT_FAILURE);
|
if ( strcmp( msg, "Set_255,Message_1" ) )
|
||||||
msg = ChfGetMessage(CHF_MODULE_ID, 2, "Default_2");
|
exit( EXIT_FAILURE );
|
||||||
if(strcmp(msg, "Default_2")) 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 */
|
/* Generate a condition and check descriptor; this is line 46 */
|
||||||
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
||||||
|
|
||||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||||
if(
|
exit( EXIT_FAILURE );
|
||||||
d->module_id != CHF_MODULE_ID
|
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 3 || d->severity != CHF_WARNING || d->line_number != 46 ||
|
||||||
|| d->condition_code != 3
|
strcmp( d->file_name, "test07.c" ) || strcmp( d->message, "Set_255,Arg_456,Message_3" ) || d->next != NULL )
|
||||||
|| d->severity != CHF_WARNING
|
exit( EXIT_FAILURE );
|
||||||
|| 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 */
|
/* Generate another condition and check; this is line 60 */
|
||||||
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
||||||
|
|
||||||
if((e = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
if ( ( e = ChfGetTopCondition() ) == NULL )
|
||||||
if(
|
exit( EXIT_FAILURE );
|
||||||
e->module_id != CHF_MODULE_ID
|
if ( e->module_id != CHF_MODULE_ID || e->condition_code != 4 || e->severity != CHF_INFO || e->line_number != 60 ||
|
||||||
|| e->condition_code != 4
|
strcmp( e->file_name, "test07.c" ) || strcmp( e->message, "Set_255,Arg_arg,Message_4" ) || e->next != d )
|
||||||
|| e->severity != CHF_INFO
|
exit( EXIT_FAILURE );
|
||||||
|| 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 */
|
/* Discard the previous condition group and create a new one */
|
||||||
ChfDiscard();
|
ChfDiscard();
|
||||||
|
@ -76,28 +67,22 @@ int main(int argc, char *argv[])
|
||||||
/* This is line 77 */
|
/* This is line 77 */
|
||||||
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||||
|
|
||||||
if((d = ChfGetTopCondition()) == NULL) exit(EXIT_FAILURE);
|
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||||
if(
|
exit( EXIT_FAILURE );
|
||||||
d->module_id != CHF_MODULE_ID
|
if ( d->module_id != CHF_MODULE_ID || d->condition_code != 5 || d->severity != CHF_ERROR || d->line_number != 77 ||
|
||||||
|| d->condition_code != 5
|
strcmp( d->file_name, "test07.c" ) || strcmp( d->message, "Set_255,Arg_456-789,Message_5" ) || d->next != NULL )
|
||||||
|| d->severity != CHF_ERROR
|
exit( EXIT_FAILURE );
|
||||||
|| 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 */
|
/* Exit Chf */
|
||||||
ChfExit();
|
ChfExit();
|
||||||
exit(EXIT_SUCCESS);
|
exit( EXIT_SUCCESS );
|
||||||
}
|
}
|
||||||
|
|
||||||
ChfTable message_table[] =
|
ChfTable message_table[] = {
|
||||||
{
|
{CHF_MODULE_ID, 1, "Set_255,Message_1" },
|
||||||
{ CHF_MODULE_ID, 1, "Set_255,Message_1" },
|
{CHF_MODULE_ID, 3, "Set_255,Arg_%d,Message_3" },
|
||||||
{ CHF_MODULE_ID, 3, "Set_255,Arg_%d,Message_3" },
|
{CHF_MODULE_ID, 4, "Set_255,Arg_%s,Message_4" },
|
||||||
{ CHF_MODULE_ID, 4, "Set_255,Arg_%s,Message_4" },
|
{CHF_MODULE_ID, 5, "Set_255,Arg_%d-%d,Message_5"}
|
||||||
{ 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
|
Data type definitions
|
||||||
All Data types must be SIGNED
|
All Data types must be SIGNED
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
typedef char int1;
|
typedef char int1;
|
||||||
typedef char int4;
|
typedef char int4;
|
||||||
typedef char int8;
|
typedef char int8;
|
||||||
typedef int int12;
|
typedef int int12;
|
||||||
typedef int int16;
|
typedef int int16;
|
||||||
typedef int int20;
|
typedef int int20;
|
||||||
typedef int int32;
|
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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h> /* 3.1: strcpy(), strcat() */
|
#include <string.h> /* 3.1: strcpy(), strcat() */
|
||||||
#include <unistd.h> /* isatty() */
|
#include <unistd.h> /* isatty() */
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "machdep.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 "args.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
/* Chf condition codes (main program only) */
|
/* 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>
|
#include <Chf.h>
|
||||||
|
|
||||||
#define MAIN_M_COPYRIGHT 501
|
#define MAIN_M_COPYRIGHT 501
|
||||||
#define MAIN_M_LICENSE 502
|
#define MAIN_M_LICENSE 502
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Chf parameters - Do not change.
|
Chf parameters - Do not change.
|
||||||
The ABNORMAL_EXIT_CODE is taken from stdlib.h (EXIT_FAILURE)
|
The ABNORMAL_EXIT_CODE is taken from stdlib.h (EXIT_FAILURE)
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define CONDITION_STACK_SIZE 16
|
#define CONDITION_STACK_SIZE 16
|
||||||
#define HANDLER_STACK_SIZE 8
|
#define HANDLER_STACK_SIZE 8
|
||||||
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
||||||
|
|
||||||
/* Conditional prefix and mandatory suffix to make a message catalog
|
/* Conditional prefix and mandatory suffix to make a message catalog
|
||||||
name from argv[0]
|
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_prefix[] = "./";
|
||||||
static const char cat_suffix[] = ".cat";
|
static const char cat_suffix[] = ".cat";
|
||||||
|
|
||||||
#define CAT_PREFIX_LEN (sizeof(cat_prefix)+1)
|
#define CAT_PREFIX_LEN ( sizeof( cat_prefix ) + 1 )
|
||||||
#define CAT_SUFFIX_LEN (sizeof(cat_suffix)+1)
|
#define CAT_SUFFIX_LEN ( sizeof( cat_suffix ) + 1 )
|
||||||
|
|
||||||
|
static void adjust_setlocale( void )
|
||||||
static void adjust_setlocale(void)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf( stderr, "saturn-W-locale probably bad; reverting to C locale\n" );
|
||||||
"saturn-W-locale probably bad; reverting to C locale\n");
|
|
||||||
|
|
||||||
putenv("LC_ALL=C");
|
putenv( "LC_ALL=C" );
|
||||||
putenv("LC_COLLATE=C");
|
putenv( "LC_COLLATE=C" );
|
||||||
putenv("LC_CTYPE=C");
|
putenv( "LC_CTYPE=C" );
|
||||||
putenv("LC_MESSAGES=C");
|
putenv( "LC_MESSAGES=C" );
|
||||||
putenv("LC_MONETARY=C");
|
putenv( "LC_MONETARY=C" );
|
||||||
putenv("LC_NUMERIC=C");
|
putenv( "LC_NUMERIC=C" );
|
||||||
putenv("LC_TIME=C");
|
putenv( "LC_TIME=C" );
|
||||||
putenv("LANG=C");
|
putenv( "LANG=C" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : main
|
.title : main
|
||||||
|
@ -182,98 +176,89 @@ static void adjust_setlocale(void)
|
||||||
- made Chf initialization more robust with respect to bad locales
|
- 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 st;
|
||||||
int retry = 0;
|
int retry = 0;
|
||||||
|
|
||||||
if((cat_name = malloc(strlen(argv[0])+CAT_PREFIX_LEN+CAT_SUFFIX_LEN+1))
|
if ( ( cat_name = malloc( strlen( argv[ 0 ] ) + CAT_PREFIX_LEN + CAT_SUFFIX_LEN + 1 ) ) == NULL ) {
|
||||||
== NULL)
|
fprintf( stderr, "saturn-E-cat_name initialization failed\n" );
|
||||||
{
|
exit( ABNORMAL_EXIT_CODE );
|
||||||
fprintf(stderr, "saturn-E-cat_name initialization failed\n");
|
|
||||||
exit(ABNORMAL_EXIT_CODE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate catalog name, without optional prefix */
|
/* Generate catalog name, without optional prefix */
|
||||||
strcpy(cat_name, argv[0]);
|
strcpy( cat_name, argv[ 0 ] );
|
||||||
strcat(cat_name, cat_suffix);
|
strcat( cat_name, cat_suffix );
|
||||||
|
|
||||||
/* 3.15: Retry the initialization steps below two times; before trying
|
/* 3.15: Retry the initialization steps below two times; before trying
|
||||||
the second time, adjust the setlocale() environment variables
|
the second time, adjust the setlocale() environment variables
|
||||||
with adjust_setlocale()
|
with adjust_setlocale()
|
||||||
*/
|
*/
|
||||||
while(retry < 2)
|
while ( retry < 2 ) {
|
||||||
{
|
/* Chf initialization with msgcat subsystem; notice that on
|
||||||
/* Chf initialization with msgcat subsystem; notice that on
|
some systems (e.g. Digital UNIX) catopen() can succeed even
|
||||||
some systems (e.g. Digital UNIX) catopen() can succeed even
|
if it was not able to open the right message catalog;
|
||||||
if it was not able to open the right message catalog;
|
better try it now.
|
||||||
better try it now.
|
*/
|
||||||
*/
|
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||||
if((st = ChfMsgcatInit(
|
CHF_DEFAULT, /* Options */
|
||||||
argv[0], /* Application's name */
|
cat_name, /* Name of the message catalog */
|
||||||
CHF_DEFAULT, /* Options */
|
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||||
cat_name, /* Name of the message catalog */
|
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
) ) != CHF_S_OK ||
|
||||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL ) == NULL )
|
||||||
)) != CHF_S_OK
|
fprintf( stderr, "saturn-E-Primary Chf initialization failed (%d)\n", st );
|
||||||
||
|
|
||||||
ChfGetMessage(CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL) == NULL)
|
|
||||||
fprintf(stderr,
|
|
||||||
"saturn-E-Primary Chf initialization failed (%d)\n", st);
|
|
||||||
|
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Bring down Chf before initializing it again */
|
/* Bring down Chf before initializing it again */
|
||||||
if(st == CHF_S_OK) ChfExit();
|
if ( st == CHF_S_OK )
|
||||||
|
ChfExit();
|
||||||
|
|
||||||
/* Try alternate message catalog name (with prefix) */
|
/* Try alternate message catalog name (with prefix) */
|
||||||
strcpy(cat_name, cat_prefix);
|
strcpy( cat_name, cat_prefix );
|
||||||
strcat(cat_name, argv[0]);
|
strcat( cat_name, argv[ 0 ] );
|
||||||
strcat(cat_name, cat_suffix);
|
strcat( cat_name, cat_suffix );
|
||||||
|
|
||||||
if((st = ChfMsgcatInit(
|
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||||
argv[0], /* Application's name */
|
CHF_DEFAULT, /* Options */
|
||||||
CHF_DEFAULT, /* Options */
|
cat_name, /* Name of the message catalog */
|
||||||
cat_name, /* Name of the message catalog */
|
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
) ) != CHF_S_OK ||
|
||||||
)) != CHF_S_OK
|
ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL ) == NULL )
|
||||||
||
|
fprintf( stderr, "saturn-E-Alternate Chf initialization failed (%d)\n", st );
|
||||||
ChfGetMessage(CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL) == NULL)
|
|
||||||
fprintf(stderr,
|
|
||||||
"saturn-E-Alternate Chf initialization failed (%d)\n",
|
|
||||||
st);
|
|
||||||
|
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Bring down Chf before initializing it again */
|
/* Bring down Chf before initializing it again */
|
||||||
if(st == CHF_S_OK) ChfExit();
|
if ( st == CHF_S_OK )
|
||||||
|
ChfExit();
|
||||||
|
|
||||||
/* Attempt to adjust setlocale() environment variables */
|
/* Attempt to adjust setlocale() environment variables */
|
||||||
if(retry++ == 0) adjust_setlocale();
|
if ( retry++ == 0 )
|
||||||
|
adjust_setlocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(retry == 2)
|
if ( retry == 2 ) {
|
||||||
{
|
fprintf( stderr, "saturn-F-Application aborted\n" );
|
||||||
fprintf(stderr, "saturn-F-Application aborted\n");
|
exit( ABNORMAL_EXIT_CODE );
|
||||||
exit(ABNORMAL_EXIT_CODE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cat_name no longer needed */
|
/* 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 */
|
/* 3.9: Print out MAIN_M_COPYRIGHT and MAIN_M_LICENSE on stdout now */
|
||||||
fprintf(stdout, ChfGetMessage(CHF_MODULE_ID, MAIN_M_COPYRIGHT, ""),
|
fprintf( stdout, ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, "" ), "$Revision: 4.1 $" );
|
||||||
"$Revision: 4.1 $");
|
fprintf( stdout, ChfGetMessage( CHF_MODULE_ID, MAIN_M_LICENSE, "" ) );
|
||||||
fprintf(stdout, ChfGetMessage(CHF_MODULE_ID, MAIN_M_LICENSE, ""));
|
|
||||||
|
|
||||||
/* Initialize GUI and associated lcd display emulation module */
|
/* Initialize GUI and associated lcd display emulation module */
|
||||||
InitializeGui(argc, argv);
|
InitializeGui( argc, argv );
|
||||||
|
|
||||||
/* Initialize serial port emulation.
|
/* Initialize serial port emulation.
|
||||||
This function returns the name of the slave side of the pty;
|
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
|
a condition containing the same information and displays the pty name
|
||||||
on the main emulator's window.
|
on the main emulator's window.
|
||||||
*/
|
*/
|
||||||
(void)SerialInit();
|
( void )SerialInit();
|
||||||
|
|
||||||
/* Initialize emulator proper */
|
/* Initialize emulator proper */
|
||||||
EmulatorInit();
|
EmulatorInit();
|
||||||
|
|
||||||
/* 3.15: Repeat copyright message on GUI if stdout is not a tty */
|
/* 3.15: Repeat copyright message on GUI if stdout is not a tty */
|
||||||
if(! isatty(fileno(stdout)))
|
if ( !isatty( fileno( stdout ) ) ) {
|
||||||
{
|
ChfCondition MAIN_M_LICENSE, CHF_INFO ChfEnd;
|
||||||
ChfCondition MAIN_M_LICENSE, CHF_INFO ChfEnd;
|
ChfCondition MAIN_M_COPYRIGHT, CHF_INFO, "$Revision: 4.1 $" ChfEnd;
|
||||||
ChfCondition MAIN_M_COPYRIGHT, CHF_INFO, "$Revision: 4.1 $" ChfEnd;
|
|
||||||
|
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(args.monitor)
|
if ( args.monitor ) {
|
||||||
{
|
/* Invoke Monitor */
|
||||||
/* Invoke Monitor */
|
void Monitor( void );
|
||||||
void Monitor(void);
|
Monitor();
|
||||||
Monitor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
/* Call Emulator directly */
|
/* Call Emulator directly */
|
||||||
Emulator();
|
Emulator();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
1483
src/modules.c
1483
src/modules.c
File diff suppressed because it is too large
Load diff
506
src/modules.h
506
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_MOD 6
|
||||||
#define N_PAGE_TABLE_ENTRIES 16384
|
#define N_PAGE_TABLE_ENTRIES 16384
|
||||||
#define N_ROM_SIZE 512*1024*2
|
#define N_ROM_SIZE 512 * 1024 * 2
|
||||||
#define N_RAM_SIZE 128*1024*2
|
#define N_RAM_SIZE 128 * 1024 * 2
|
||||||
#define N_FLASH_SIZE_49 2048*1024*2 /* 3.2 */
|
#define N_FLASH_SIZE_49 2048 * 1024 * 2 /* 3.2 */
|
||||||
#define N_RAM_SIZE_49 512*1024*2 /* 3.2 */
|
#define N_RAM_SIZE_49 512 * 1024 * 2 /* 3.2 */
|
||||||
|
|
||||||
/* 2.4: Port_1 (CE2) size */
|
/* 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 */
|
/* 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_CHECK_OB_SIZE 128
|
||||||
#define MOD_MAP_TABLE_OB_SIZE 512
|
#define MOD_MAP_TABLE_OB_SIZE 512
|
||||||
|
|
||||||
/* 2.7: Number of entries in module config cache */
|
/* 2.7: Number of entries in module config cache */
|
||||||
#define N_MOD_CACHE_ENTRIES 8
|
#define N_MOD_CACHE_ENTRIES 8
|
||||||
|
|
||||||
#define MOD_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
|
||||||
|
|
||||||
|
#define MOD_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Macros
|
Macros
|
||||||
|
|
||||||
ModAddress returns the base address of a page, given its number (Address)
|
ModAddress returns the base address of a page, given its number (Address)
|
||||||
ModOffset returns the page offset of an address (int)
|
ModOffset returns the page offset of an address (int)
|
||||||
ModPage returns the page number of an address (Address)
|
ModPage returns the page number of an address (Address)
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define ModAddress(page) ((Address)(page) << 6)
|
#define ModAddress( page ) ( ( Address )( page ) << 6 )
|
||||||
#define ModPage(address) ((int)(((address) & 0xFFFC0) >> 6))
|
#define ModPage( address ) ( ( int )( ( ( address ) & 0xFFFC0 ) >> 6 ) )
|
||||||
#define ModOffset(address) ((address) & 0x0003F)
|
#define ModOffset( address ) ( ( address ) & 0x0003F )
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ModDescription
|
ModDescription
|
||||||
|
|
||||||
This const array contains an entry for each peripheral module connected
|
This const array contains an entry for each peripheral module connected
|
||||||
to the peripheral bus of the Saturn CPU; the entry describes the
|
to the peripheral bus of the Saturn CPU; the entry describes the
|
||||||
characteristics of the module.
|
characteristics of the module.
|
||||||
|
|
||||||
name: the mnemonic name of the module; the Saturn CPU doesn't
|
name: the mnemonic name of the module; the Saturn CPU doesn't
|
||||||
actually use this information, but it's still useful during
|
actually use this information, but it's still useful during
|
||||||
debugging.
|
debugging.
|
||||||
|
|
||||||
id: the ID of the module, returned by the C=ID instruction
|
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
|
access_prio: the access priority of the module, when the address spaces of
|
||||||
more than one module overlap. Higher values correspond to
|
more than one module overlap. Higher values correspond to
|
||||||
higher priorities.
|
higher priorities.
|
||||||
|
|
||||||
The configuration priority of the module, when there is more
|
The configuration priority of the module, when there is more
|
||||||
than one unconfigured module on the peripheral bus, is
|
than one unconfigured module on the peripheral bus, is
|
||||||
determined implicitly by the order in which the module
|
determined implicitly by the order in which the module
|
||||||
descriptions into the array. The modules that come first
|
descriptions into the array. The modules that come first
|
||||||
in the array are configured first.
|
in the array are configured first.
|
||||||
|
|
||||||
init: this function is called, without arguments, during VM startup
|
init: this function is called, without arguments, during VM startup
|
||||||
to initialize the device. For example, the initialization
|
to initialize the device. For example, the initialization
|
||||||
function for the ROM module will read the ROM image from
|
function for the ROM module will read the ROM image from
|
||||||
disk and store them into the module status structure.
|
disk and store them into the module status structure.
|
||||||
|
|
||||||
read: this function reads a nibble from the module. It receives the
|
read: this function reads a nibble from the module. It receives the
|
||||||
relative address of the nibble to be read. The read function
|
relative address of the nibble to be read. The read function
|
||||||
can return an interrupt request for the CPU.
|
can return an interrupt request for the CPU.
|
||||||
|
|
||||||
write: this function writes a nibble to the module. It receives the
|
write: this function writes a nibble to the module. It receives the
|
||||||
relative address and the value of the nibble to be written.
|
relative address and the value of the nibble to be written.
|
||||||
The write function can return an interrupt request for the CPU.
|
The write function can return an interrupt request for the CPU.
|
||||||
|
|
||||||
r_config: this flag contains the configuration status of the module after
|
r_config: this flag contains the configuration status of the module after
|
||||||
a bus reset. If the after-reset configuration status is
|
a bus reset. If the after-reset configuration status is
|
||||||
MOD_CONFIGURED, the module can never be unconfigured.
|
MOD_CONFIGURED, the module can never be unconfigured.
|
||||||
|
|
||||||
r_abs_base_addr: absolute base address of the module after a bus reset.
|
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
|
It should be set only if the module is at least partially
|
||||||
configured automatically after a bus reset.
|
configured automatically after a bus reset.
|
||||||
|
|
||||||
r_size: size of the address window of the module 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
|
It should be set only if the module is at least partially
|
||||||
configured automatically after a bus reset.
|
configured automatically after a bus reset.
|
||||||
|
|
||||||
map_flags: special map flags:
|
map_flags: special map flags:
|
||||||
MOD_MAP_FLAGS_ABS pass absolute addresses to module
|
MOD_MAP_FLAGS_ABS pass absolute addresses to module
|
||||||
read/write functions
|
read/write functions
|
||||||
|
|
||||||
Notice that the current implementation requires that the index of
|
Notice that the current implementation requires that the index of
|
||||||
the HDW registers in the mod_description table must be fixed
|
the HDW registers in the mod_description table must be fixed
|
||||||
and equal to MOD_HDW_INDEX... this is unfortunate.
|
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
|
enum ModConfig { MOD_UNCONFIGURED, MOD_SIZE_CONFIGURED, MOD_CONFIGURED };
|
||||||
{
|
|
||||||
MOD_UNCONFIGURED,
|
struct ModDescriptionEntry {
|
||||||
MOD_SIZE_CONFIGURED,
|
char* name;
|
||||||
MOD_CONFIGURED
|
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
|
#define MOD_HDW_INDEX 1
|
||||||
{
|
typedef const struct ModDescriptionEntry ModDescription[ N_MOD ];
|
||||||
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 */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MOD_HDW_INDEX 1
|
|
||||||
typedef const struct ModDescriptionEntry ModDescription[N_MOD];
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ModMapInfo
|
ModMapInfo
|
||||||
|
|
||||||
This array contains an entry for each peripheral module connected
|
This array contains an entry for each peripheral module connected
|
||||||
to the peripheral bus of the Saturn CPU; the entry describes the
|
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.
|
config: contains the current configuration status of the module.
|
||||||
|
|
||||||
abs_base_addr: contains the current absolute base address 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.
|
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
|
struct ModMapInfoEntry {
|
||||||
{
|
enum ModConfig config;
|
||||||
enum ModConfig config;
|
Address abs_base_addr;
|
||||||
Address abs_base_addr;
|
Address size;
|
||||||
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'
|
This array contains an entry (of type ModPageTableEntry) for each 'page'
|
||||||
(of size #40 nibbles) of the Saturn CPU physical address space. For
|
(of size #40 nibbles) of the Saturn CPU physical address space. For
|
||||||
each page, the following information is stored:
|
each page, the following information is stored:
|
||||||
|
|
||||||
index: the index of the module that responds to the address range of
|
index: the index of the module that responds to the address range of
|
||||||
the page in the ModDescription table.The special value
|
the page in the ModDescription table.The special value
|
||||||
MOD_NO_MOD_INDEX indicates that no module responds to the
|
MOD_NO_MOD_INDEX indicates that no module responds to the
|
||||||
address range.
|
address range.
|
||||||
|
|
||||||
rel_base_addr: the relative base address of the page in the address
|
rel_base_addr: the relative base address of the page in the address
|
||||||
space of the module that responds to the address range of
|
space of the module that responds to the address range of
|
||||||
the page, if any.
|
the page, if any.
|
||||||
|
|
||||||
read, write: the read/write functions of the module that responds to the
|
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:
|
The Saturn Physical Address (SPA) is divided into two portions:
|
||||||
|
|
||||||
|
@ -315,18 +303,16 @@ typedef struct ModMapInfoEntry ModMapInfo[N_MOD];
|
||||||
is called.
|
is called.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
struct ModPageTableEntry
|
struct ModPageTableEntry {
|
||||||
{
|
int index;
|
||||||
int index;
|
#define MOD_NO_MOD_INDEX ( -1 )
|
||||||
#define MOD_NO_MOD_INDEX (-1)
|
|
||||||
|
|
||||||
Address rel_base_addr;
|
Address rel_base_addr;
|
||||||
ModReadFunction read;
|
ModReadFunction read;
|
||||||
ModWriteFunction write;
|
ModWriteFunction write;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ModPageTableEntry ModPageTable[N_PAGE_TABLE_ENTRIES];
|
typedef struct ModPageTableEntry ModPageTable[ N_PAGE_TABLE_ENTRIES ];
|
||||||
|
|
||||||
|
|
||||||
/* struct ModCache (2.7)
|
/* 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.
|
The .link field links all cached struct ModMap together.
|
||||||
*/
|
*/
|
||||||
struct ModCacheTableEntry
|
struct ModCacheTableEntry {
|
||||||
{
|
|
||||||
Address tag;
|
Address tag;
|
||||||
struct ModMap *map_ptr;
|
struct ModMap* map_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModCache
|
struct ModCache {
|
||||||
{
|
struct ModCacheTableEntry config[ N_MOD_CACHE_ENTRIES ];
|
||||||
struct ModCacheTableEntry config[N_MOD_CACHE_ENTRIES];
|
|
||||||
int victim;
|
int victim;
|
||||||
|
|
||||||
struct ModMap *(unconfig[N_MOD]);
|
struct ModMap*( unconfig[ N_MOD ] );
|
||||||
|
|
||||||
int config_point;
|
int config_point;
|
||||||
int ref_count;
|
int ref_count;
|
||||||
|
|
||||||
struct ModMap *link;
|
struct ModMap* link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct ModMap
|
struct ModMap
|
||||||
|
|
||||||
This structure contains all the mapping information about the peripheral
|
This structure contains all the mapping information about the peripheral
|
||||||
modules of the Saturn CPU. Its components are:
|
modules of the Saturn CPU. Its components are:
|
||||||
|
|
||||||
map_info: this array describes the dynamic mapping information of
|
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
|
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
|
cache (2.7): this structure holds caching information used to speed up
|
||||||
module config/unconfig instructions
|
module config/unconfig instructions
|
||||||
|
|
||||||
*/
|
*/
|
||||||
struct ModMap
|
struct ModMap {
|
||||||
{
|
ModMapInfo map_info;
|
||||||
ModMapInfo map_info;
|
ModPageTable page_table;
|
||||||
ModPageTable page_table;
|
struct ModCache cache;
|
||||||
struct ModCache cache;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct ModStatus
|
struct ModStatus
|
||||||
|
|
||||||
This structure contains the actual status of all peripheral modules of the
|
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
|
Saturn CPU. The status of all modules is centralized to allow any device
|
||||||
to easily access the status of other devices.
|
to easily access the status of other devices.
|
||||||
|
|
||||||
struct ModHdw
|
struct ModHdw
|
||||||
|
|
||||||
This substructure contains the status of all peripheral devices controlled
|
This substructure contains the status of all peripheral devices controlled
|
||||||
by the hdw module.
|
by the hdw module.
|
||||||
|
@ -429,188 +410,177 @@ struct ModMap
|
||||||
configuration-specific ROM/RAM emulation module.
|
configuration-specific ROM/RAM emulation module.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
struct ModHdw48Accel
|
struct ModHdw48Accel {
|
||||||
{
|
XAddress bs_address; /* Bank Switcher ext. address */
|
||||||
XAddress bs_address; /* Bank Switcher ext. address */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModHdw49Accel
|
struct ModHdw49Accel {
|
||||||
{
|
XAddress view[ 2 ]; /* Base of Flash views */
|
||||||
XAddress view[2]; /* Base of Flash views */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModHdw
|
struct ModHdw {
|
||||||
{
|
Nibble hdw[ N_HDW_SIZE ]; /* HDW registers */
|
||||||
Nibble hdw[N_HDW_SIZE]; /* HDW registers */
|
|
||||||
|
|
||||||
/* LCD driver */
|
/* LCD driver */
|
||||||
Address lcd_base_addr; /* LCD driver base address */
|
Address lcd_base_addr; /* LCD driver base address */
|
||||||
int lcd_on; /* LCD driver enable flag */
|
int lcd_on; /* LCD driver enable flag */
|
||||||
int lcd_contrast; /* LCD contrast value */
|
int lcd_contrast; /* LCD contrast value */
|
||||||
int lcd_vlc; /* LCD vertical line count */
|
int lcd_vlc; /* LCD vertical line count */
|
||||||
int lcd_offset; /* LCD horizontal offset */
|
int lcd_offset; /* LCD horizontal offset */
|
||||||
int lcd_line_offset; /* LCD line offset */
|
int lcd_line_offset; /* LCD line offset */
|
||||||
Address lcd_menu_addr; /* LCD menu base address */
|
Address lcd_menu_addr; /* LCD menu base address */
|
||||||
int lcd_ann; /* LCD annunciators status */
|
int lcd_ann; /* LCD annunciators status */
|
||||||
|
|
||||||
/* Timers */
|
/* Timers */
|
||||||
Nibble t1_ctrl; /* Timer 1 control */
|
Nibble t1_ctrl; /* Timer 1 control */
|
||||||
#define T1_CTRL_EXTRA 0x01
|
#define T1_CTRL_EXTRA 0x01
|
||||||
#define T1_CTRL_INT 0x02
|
#define T1_CTRL_INT 0x02
|
||||||
#define T1_CTRL_WAKE 0x04
|
#define T1_CTRL_WAKE 0x04
|
||||||
#define T1_CTRL_SREQ 0x08
|
#define T1_CTRL_SREQ 0x08
|
||||||
|
|
||||||
Nibble t2_ctrl; /* Timer 2 control */
|
Nibble t2_ctrl; /* Timer 2 control */
|
||||||
#define T2_CTRL_TRUN 0x01
|
#define T2_CTRL_TRUN 0x01
|
||||||
#define T2_CTRL_INT 0x02
|
#define T2_CTRL_INT 0x02
|
||||||
#define T2_CTRL_WAKE 0x04
|
#define T2_CTRL_WAKE 0x04
|
||||||
#define T2_CTRL_SREQ 0x08
|
#define T2_CTRL_SREQ 0x08
|
||||||
|
|
||||||
Nibble t1_val; /* Timer 1 value */
|
Nibble t1_val; /* Timer 1 value */
|
||||||
int32 t2_val; /* Timer 2 value */
|
int32 t2_val; /* Timer 2 value */
|
||||||
|
|
||||||
/* 2.4: New member required to support Port emulation */
|
/* 2.4: New member required to support Port emulation */
|
||||||
Nibble card_status; /* Card status (hdw register 0x0F) */
|
Nibble card_status; /* Card status (hdw register 0x0F) */
|
||||||
#define NCE3_CARD_PRESENT 0x01
|
#define NCE3_CARD_PRESENT 0x01
|
||||||
#define CE2_CARD_PRESENT 0x02
|
#define CE2_CARD_PRESENT 0x02
|
||||||
#define NCE3_CARD_WE 0x04
|
#define NCE3_CARD_WE 0x04
|
||||||
#define CE2_CARD_WE 0x08
|
#define CE2_CARD_WE 0x08
|
||||||
|
|
||||||
/* 2.4: Hw configuration-specific members used as accelerators;
|
/* 2.4: Hw configuration-specific members used as accelerators;
|
||||||
accel_valid is non-zero if the accelerators are valid
|
accel_valid is non-zero if the accelerators are valid
|
||||||
*/
|
*/
|
||||||
int accel_valid;
|
int accel_valid;
|
||||||
|
|
||||||
union
|
union {
|
||||||
{
|
struct ModHdw48Accel a48;
|
||||||
struct ModHdw48Accel a48;
|
struct ModHdw49Accel a49;
|
||||||
struct ModHdw49Accel a49;
|
} accel;
|
||||||
} accel;
|
|
||||||
|
|
||||||
/* 2.5: Serial port buffer registers */
|
/* 2.5: Serial port buffer registers */
|
||||||
int8 serial_rbr;
|
int8 serial_rbr;
|
||||||
int8 serial_tbr;
|
int8 serial_tbr;
|
||||||
|
|
||||||
/* Misc */
|
/* Misc */
|
||||||
int16 crc; /* CRC */
|
int16 crc; /* CRC */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModStatus
|
struct ModStatus {
|
||||||
{
|
struct ModHdw hdw; /* HDW status */
|
||||||
struct ModHdw hdw; /* HDW status */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModStatus_48
|
struct ModStatus_48 {
|
||||||
{
|
Nibble rom[ N_ROM_SIZE ]; /* Internal ROM */
|
||||||
Nibble rom[N_ROM_SIZE]; /* Internal ROM */
|
Nibble ram[ N_RAM_SIZE ]; /* Internal RAM */
|
||||||
Nibble ram[N_RAM_SIZE]; /* Internal RAM */
|
Nibble port_1[ N_PORT_1_SIZE ]; /* 2.4: Port_1 (CE2) storage */
|
||||||
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
|
#ifdef N_PORT_2_BANK
|
||||||
Nibble port_2[N_PORT_2_SIZE];
|
Nibble port_2[ N_PORT_2_SIZE ];
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModStatus_49
|
struct ModStatus_49 {
|
||||||
{
|
Nibble flash[ N_FLASH_SIZE_49 ]; /* Internal Flash ROM */
|
||||||
Nibble flash[N_FLASH_SIZE_49]; /* Internal Flash ROM */
|
Nibble ram[ N_RAM_SIZE_49 ]; /* Internal RAM */
|
||||||
Nibble ram[N_RAM_SIZE_49]; /* Internal RAM */
|
Nibble *ce2, *nce3; /* ERAM bases */
|
||||||
Nibble *ce2, *nce3; /* ERAM bases */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Global variables
|
Global variables
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
extern struct ModStatus mod_status;
|
extern struct ModStatus mod_status;
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Chf condition codes
|
Chf condition codes
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define MOD_I_CALLED 101 /* Function %s called */
|
#define MOD_I_CALLED 101 /* Function %s called */
|
||||||
#define MOD_I_INITIALIZING 102 /* Initializing module %s */
|
#define MOD_I_INITIALIZING 102 /* Initializing module %s */
|
||||||
#define MOD_I_RESETTING 103 /* Resetting module %s */
|
#define MOD_I_RESETTING 103 /* Resetting module %s */
|
||||||
#define MOD_I_GET_ID 106 /* ModGetID returning %x */
|
#define MOD_I_GET_ID 106 /* ModGetID returning %x */
|
||||||
#define MOD_I_CONFIG 107 /* ModConfig %s %x %x completed */
|
#define MOD_I_CONFIG 107 /* ModConfig %s %x %x completed */
|
||||||
#define MOD_I_UNCONFIG 108 /* ModUnconfig %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_SAVING 109 /* Saving status of module %s */
|
||||||
#define MOD_I_NOT_IMPLEMENTED 110 /* Function %s not implemented */
|
#define MOD_I_NOT_IMPLEMENTED 110 /* Function %s not implemented */
|
||||||
#define MOD_I_REVISION 111 /* Modules revision: %s */
|
#define MOD_I_REVISION 111 /* Modules revision: %s */
|
||||||
#define MOD_I_BS_ADDRESS 112 /* 2.4: Bank Switcher address: %x */
|
#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_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_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_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_UNCONFIG 116 /* 2.7: Cached ModUnconfig completed */
|
||||||
#define MOD_I_CACHED_CONFIG 117 /* 2.7: Cached ModConfig %x comp. */
|
#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_HIT 118 /* 2.7: Late unconfig hit */
|
||||||
#define MOD_I_UNCONFIG_L_MISS 119 /* 2.7: Late unconfig miss */
|
#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_CONFIG 202 /* Bad ModConfig %x ignored */
|
||||||
#define MOD_W_BAD_UNCONFIG 203 /* Bad ModUnconfig %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_WRITE 204 /* Bad HdwWrite %x, %x */
|
||||||
#define MOD_W_HDW_READ 205 /* Bad HdwRead %x */
|
#define MOD_W_HDW_READ 205 /* Bad HdwRead %x */
|
||||||
#define MOD_W_RESETTING_ALL 206 /* Resetting all modules */
|
#define MOD_W_RESETTING_ALL 206 /* Resetting all modules */
|
||||||
#define MOD_W_RAM_INIT 207 /* Can't initialize internal RAM */
|
#define MOD_W_RAM_INIT 207 /* Can't initialize internal RAM */
|
||||||
#define MOD_W_HDW_INIT 208 /* Can't initialize HDW */
|
#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_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_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_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_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_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_READ 301 /* Read unmapped addr %x */
|
||||||
#define MOD_E_BAD_WRITE 302 /* Write unmapped addr %x datum %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_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_RAM_SAVE 304 /* Can't save internal RAM status */
|
||||||
#define MOD_E_HDW_SAVE 305 /* Can't save HDW 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_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_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_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_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_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_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_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_MAP_SAVE 401 /* Can't save mod_map information */
|
||||||
#define MOD_F_ROM_INIT 402 /* Can't initialize internal ROM */
|
#define MOD_F_ROM_INIT 402 /* Can't initialize internal ROM */
|
||||||
#define MOD_F_MAP_ALLOC 403 /* Dynamic map allocation failed */
|
#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_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_CHAIN_CORRUPTED 405 /* 2.7: ModMap chain corrupted */
|
||||||
#define MOD_F_NO_VICTIM 406 /* 2.7: No cache victim after flush */
|
#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_MOD_STATUS_ALLOC 407 /* 3.2: ModStatus_xx alloc failed %d */
|
||||||
#define MOD_F_NO_DESCRIPTION 408 /* 3.2: No module description */
|
#define MOD_F_NO_DESCRIPTION 408 /* 3.2: No module description */
|
||||||
#define MOD_M_NOT_MAPPED 501 /* Address %x not mapped */
|
#define MOD_M_NOT_MAPPED 501 /* Address %x not mapped */
|
||||||
#define MOD_M_MAPPED 502 /* Address %x mapped to %s:%x */
|
#define MOD_M_MAPPED 502 /* Address %x mapped to %s:%x */
|
||||||
#define MOD_M_MAP_TABLE_TITLE 503 /* */
|
#define MOD_M_MAP_TABLE_TITLE 503 /* */
|
||||||
#define MOD_M_MAP_TABLE_ROW 504 /* %s %x %x %s */
|
#define MOD_M_MAP_TABLE_ROW 504 /* %s %x %x %s */
|
||||||
#define MOD_M_MAP_CONFIGURED 505 /* Configured */
|
#define MOD_M_MAP_CONFIGURED 505 /* Configured */
|
||||||
#define MOD_M_MAP_SZ_CONFIGURED 506 /* Size configured */
|
#define MOD_M_MAP_SZ_CONFIGURED 506 /* Size configured */
|
||||||
#define MOD_M_MAP_UNCONFIGURED 507 /* Unconfigured */
|
#define MOD_M_MAP_UNCONFIGURED 507 /* Unconfigured */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Function prototypes
|
Function prototypes
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
void ModSelectDescription(const char *hw);
|
void ModSelectDescription( const char* hw );
|
||||||
void ModRegisterDescription(ModDescription p);
|
void ModRegisterDescription( ModDescription p );
|
||||||
void ModInit(void);
|
void ModInit( void );
|
||||||
void ModSave(void);
|
void ModSave( void );
|
||||||
void ModReset(void);
|
void ModReset( void );
|
||||||
|
|
||||||
/* Configuration */
|
/* Configuration */
|
||||||
Address ModGetID(void);
|
Address ModGetID( void );
|
||||||
void ModConfig(Address config_info);
|
void ModConfig( Address config_info );
|
||||||
void ModUnconfig(Address unconfig_info);
|
void ModUnconfig( Address unconfig_info );
|
||||||
|
|
||||||
/* Read/Write */
|
/* Read/Write */
|
||||||
Nibble FetchNibble(Address addr);
|
Nibble FetchNibble( Address addr );
|
||||||
Nibble ReadNibble(Address addr);
|
Nibble ReadNibble( Address addr );
|
||||||
void WriteNibble(Address addr, Nibble datum);
|
void WriteNibble( Address addr, Nibble datum );
|
||||||
|
|
||||||
/* Monitor */
|
/* Monitor */
|
||||||
void ModMapCheck(Address addr, char ob[MOD_MAP_CHECK_OB_SIZE]);
|
void ModMapCheck( Address addr, char ob[ MOD_MAP_CHECK_OB_SIZE ] );
|
||||||
void ModMapTable(char ob[MOD_MAP_TABLE_OB_SIZE]);
|
void ModMapTable( char ob[ MOD_MAP_TABLE_OB_SIZE ] );
|
||||||
|
|
332
src/monitor.c
332
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 "args.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID CPU_CHF_MODULE_ID
|
#define CHF_MODULE_ID CPU_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Macro & Data type definitions
|
Macro & Data type definitions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define LINE_BUFFER_SIZE 512
|
#define LINE_BUFFER_SIZE 512
|
||||||
#define TOK_DELIMITERS " \t\n"
|
#define TOK_DELIMITERS " \t\n"
|
||||||
#define ADDRESS_FMT "%x"
|
#define ADDRESS_FMT "%x"
|
||||||
#define COUNT_FMT "%d"
|
#define COUNT_FMT "%d"
|
||||||
#define PROMPT "> "
|
#define PROMPT "> "
|
||||||
#define OK 0
|
#define OK 0
|
||||||
#define FAILED 1
|
#define FAILED 1
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Private functions - Command line parse
|
Private functions - Command line parse
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Read an Address from the command line */
|
/* Read an Address from the command line */
|
||||||
static int ReadHexAddress(Address *addr)
|
static int ReadHexAddress( Address* addr )
|
||||||
{
|
{
|
||||||
char *p = strtok((char *)NULL, TOK_DELIMITERS);
|
char* p = strtok( ( char* )NULL, TOK_DELIMITERS );
|
||||||
return (p == (char *)NULL ||
|
return ( p == ( char* )NULL || sscanf( p, ADDRESS_FMT, addr ) != 1 ) ? FAILED : OK;
|
||||||
sscanf(p, ADDRESS_FMT, addr) != 1) ? FAILED : OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a Nibble from the command line */
|
/* Read a Nibble from the command line */
|
||||||
static int ReadHexDatum(Nibble *n)
|
static int ReadHexDatum( Nibble* n )
|
||||||
{
|
{
|
||||||
Address addr;
|
Address addr;
|
||||||
int st;
|
int st;
|
||||||
if((st = ReadHexAddress(&addr)) == OK) *n = (Nibble)addr;
|
if ( ( st = ReadHexAddress( &addr ) ) == OK )
|
||||||
return st;
|
*n = ( Nibble )addr;
|
||||||
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a DECIMAL count from the command line */
|
/* 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);
|
char* p = strtok( ( char* )NULL, TOK_DELIMITERS );
|
||||||
return (p == (char *)NULL || sscanf(p, COUNT_FMT, count) != 1 ||
|
return ( p == ( char* )NULL || sscanf( p, COUNT_FMT, count ) != 1 || *count <= 0 ) ? FAILED : OK;
|
||||||
*count <= 0) ? FAILED : OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Private functions - Command execution
|
Private functions - Command execution
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Run the emulator; this function exits normally only when an
|
/* Run the emulator; this function exits normally only when an
|
||||||
EmulatorIntRequest() is posted and satisfied
|
EmulatorIntRequest() is posted and satisfied
|
||||||
*/
|
*/
|
||||||
static int run(void)
|
static int run( void )
|
||||||
{
|
{
|
||||||
Emulator();
|
Emulator();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the debug level */
|
/* Set the debug level */
|
||||||
static int debug(void)
|
static int debug( void )
|
||||||
{
|
{
|
||||||
Address addr;
|
Address addr;
|
||||||
if(ReadHexAddress(&addr)) return FAILED;
|
if ( ReadHexAddress( &addr ) )
|
||||||
SetDebugLevel((int)addr);
|
return FAILED;
|
||||||
return OK;
|
SetDebugLevel( ( int )addr );
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the mapping of an Address and print */
|
/* Check the mapping of an Address and print */
|
||||||
static int map_check(void)
|
static int map_check( void )
|
||||||
{
|
{
|
||||||
Address addr;
|
Address addr;
|
||||||
char ob[MOD_MAP_CHECK_OB_SIZE];
|
char ob[ MOD_MAP_CHECK_OB_SIZE ];
|
||||||
if(ReadHexAddress(&addr)) return FAILED;
|
if ( ReadHexAddress( &addr ) )
|
||||||
ModMapCheck(addr, ob);
|
return FAILED;
|
||||||
puts(ob);
|
ModMapCheck( addr, ob );
|
||||||
return OK;
|
puts( ob );
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print the current module map table */
|
/* Print the current module map table */
|
||||||
static int map(void)
|
static int map( void )
|
||||||
{
|
{
|
||||||
char ob[MOD_MAP_TABLE_OB_SIZE];
|
char ob[ MOD_MAP_TABLE_OB_SIZE ];
|
||||||
ModMapTable(ob);
|
ModMapTable( ob );
|
||||||
puts(ob);
|
puts( ob );
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write nibbles into memory */
|
/* Write nibbles into memory */
|
||||||
static int w(void)
|
static int w( void )
|
||||||
{
|
{
|
||||||
Address addr;
|
Address addr;
|
||||||
Nibble n;
|
Nibble n;
|
||||||
if(ReadHexAddress(&addr)) return FAILED;
|
if ( ReadHexAddress( &addr ) )
|
||||||
while(ReadHexDatum(&n) == OK) WriteNibble(addr++, n);
|
return FAILED;
|
||||||
return OK;
|
while ( ReadHexDatum( &n ) == OK )
|
||||||
|
WriteNibble( addr++, n );
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read nibbles from memory */
|
/* Read nibbles from memory */
|
||||||
static int r(void)
|
static int r( void )
|
||||||
{
|
{
|
||||||
Address addr;
|
Address addr;
|
||||||
int count;
|
int count;
|
||||||
if(ReadHexAddress(&addr)) return FAILED;
|
if ( ReadHexAddress( &addr ) )
|
||||||
if(ReadCount(&count)) count=1;
|
return FAILED;
|
||||||
|
if ( ReadCount( &count ) )
|
||||||
|
count = 1;
|
||||||
|
|
||||||
while(count-->0)
|
while ( count-- > 0 ) {
|
||||||
{
|
printf( "A_%05X\t%X\n", addr, ( int )FetchNibble( addr ) );
|
||||||
printf("A_%05X\t%X\n", addr, (int)FetchNibble(addr));
|
addr++;
|
||||||
addr++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disassemble */
|
/* Disassemble */
|
||||||
static int d(void)
|
static int d( void )
|
||||||
{
|
{
|
||||||
Address addr;
|
Address addr;
|
||||||
int count;
|
int count;
|
||||||
char ob[DISASSEMBLE_OB_SIZE];
|
char ob[ DISASSEMBLE_OB_SIZE ];
|
||||||
|
|
||||||
if(ReadHexAddress(&addr)) return FAILED;
|
if ( ReadHexAddress( &addr ) )
|
||||||
if(ReadCount(&count)) count=1;
|
return FAILED;
|
||||||
|
if ( ReadCount( &count ) )
|
||||||
|
count = 1;
|
||||||
|
|
||||||
while(count-->0)
|
while ( count-- > 0 ) {
|
||||||
{
|
addr = Disassemble( addr, ob );
|
||||||
addr = Disassemble(addr, ob);
|
puts( ob );
|
||||||
puts(ob);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print CPU status */
|
/* Print CPU status */
|
||||||
static int cpu(void)
|
static int cpu( void )
|
||||||
{
|
{
|
||||||
char ob[DUMP_CPU_STATUS_OB_SIZE];
|
char ob[ DUMP_CPU_STATUS_OB_SIZE ];
|
||||||
DumpCpuStatus(ob);
|
DumpCpuStatus( ob );
|
||||||
puts(ob);
|
puts( ob );
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset CPU */
|
/* Reset CPU */
|
||||||
static int reset(void)
|
static int reset( void )
|
||||||
{
|
{
|
||||||
CpuReset();
|
CpuReset();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save & Exit */
|
/* Save & Exit */
|
||||||
static int mon_exit(void)
|
static int mon_exit( void )
|
||||||
{
|
{
|
||||||
ModSave();
|
ModSave();
|
||||||
CpuSave();
|
CpuSave();
|
||||||
exit(EXIT_SUCCESS);
|
exit( EXIT_SUCCESS );
|
||||||
return OK; /* 3.1: Keep compiler happy */
|
return OK; /* 3.1: Keep compiler happy */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Quit without saving */
|
/* Quit without saving */
|
||||||
static int mon_quit(void)
|
static int mon_quit( void )
|
||||||
{
|
{
|
||||||
exit(EXIT_SUCCESS);
|
exit( EXIT_SUCCESS );
|
||||||
return OK; /* 3.1: Keep compiler happy */
|
return OK; /* 3.1: Keep compiler happy */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Command table
|
Command table
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
struct TEntry
|
struct TEntry {
|
||||||
{
|
char* name;
|
||||||
char *name;
|
char* desc;
|
||||||
char *desc;
|
int ( *function )( void );
|
||||||
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 */
|
/* Forward declaration for the Help funcion */
|
||||||
static int Help(void);
|
static int Help( void );
|
||||||
|
|
||||||
static const struct TEntry table[] =
|
static const struct TEntry table[] = {
|
||||||
{
|
{"help", "Print this information", Help },
|
||||||
{ "help", "Print this information", Help },
|
{"run", "Run the emulator with current CPU status", run },
|
||||||
{ "run", "Run the emulator with current CPU status", run },
|
{"?", "<addr>, Check address mapping", map_check},
|
||||||
{ "?", "<addr>, Check address mapping", map_check },
|
{"r", "<addr> [count], Read nibbles from memory", r },
|
||||||
{ "r", "<addr> [count], Read nibbles from memory", r },
|
{"w", "<addr> [n]..., Write nibbles into memory", w },
|
||||||
{ "w", "<addr> [n]..., Write nibbles into memory", w },
|
{"d", "<addr> [count], Disassemble starting from 'addr'", d },
|
||||||
{ "d", "<addr> [count], Disassemble starting from 'addr'", d },
|
{"cpu", "Print CPU status", cpu },
|
||||||
{ "cpu", "Print CPU status", cpu },
|
{"map", "Print the contents of the module map table", map },
|
||||||
{ "map", "Print the contents of the module map table", map },
|
{"debug", "Set the debugging level", debug },
|
||||||
{ "debug", "Set the debugging level", debug },
|
{"reset", "Reset CPU", reset },
|
||||||
{ "reset", "Reset CPU", reset },
|
{"exit", "Save emulator state & exit", mon_exit },
|
||||||
{ "exit", "Save emulator state & exit", mon_exit },
|
{"quit", "Quit emulator WITHOUT saving its state", mon_quit }
|
||||||
{ "quit", "Quit emulator WITHOUT saving its state", mon_quit }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Invoke the command 'tk' and return a status code */
|
/* Invoke the command 'tk' and return a status code */
|
||||||
static int InvokeCommand(char *tk)
|
static int InvokeCommand( char* tk )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<TableSize(table) && strcmp(tk, table[i].name); i++);
|
for ( i = 0; i < TableSize( table ) && strcmp( tk, table[ i ].name ); i++ )
|
||||||
return i==TableSize(table) ? FAILED : table[i].function();
|
;
|
||||||
|
return i == TableSize( table ) ? FAILED : table[ i ].function();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print help information */
|
/* Print help information */
|
||||||
static int Help(void)
|
static int Help( void )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<TableSize(table); i++)
|
for ( i = 0; i < TableSize( table ); i++ )
|
||||||
printf("%s\t\t%s\n", table[i].name, table[i].desc);
|
printf( "%s\t\t%s\n", table[ i ].name, table[ i ].desc );
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handler for SIGINT during monitor execution */
|
/* Handler for SIGINT during monitor execution */
|
||||||
static void sigint_handler(int s)
|
static void sigint_handler( int s ) { EmulatorIntRequest(); }
|
||||||
{
|
|
||||||
EmulatorIntRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
@ -322,58 +319,53 @@ static void sigint_handler(int s)
|
||||||
This function implements a very simple interactive monitor.
|
This function implements a very simple interactive monitor.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Monitor();
|
Monitor();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
CPU_W_BAD_MONITOR_CMD
|
CPU_W_BAD_MONITOR_CMD
|
||||||
From lower level modules
|
From lower level modules
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 18-Feb-1998, creation
|
1.1, 18-Feb-1998, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void Monitor(void)
|
void Monitor( void )
|
||||||
{
|
{
|
||||||
char cmd[LINE_BUFFER_SIZE];
|
char cmd[ LINE_BUFFER_SIZE ];
|
||||||
char old_cmd[LINE_BUFFER_SIZE];
|
char old_cmd[ LINE_BUFFER_SIZE ];
|
||||||
char *tk;
|
char* tk;
|
||||||
|
|
||||||
/* Clear old_cmd buffer */
|
/* Clear old_cmd buffer */
|
||||||
strcpy(old_cmd, "");
|
strcpy( old_cmd, "" );
|
||||||
|
|
||||||
/* Establish SIGINT handler */
|
/* Establish SIGINT handler */
|
||||||
signal(SIGINT, sigint_handler);
|
signal( SIGINT, sigint_handler );
|
||||||
|
|
||||||
/* Infinite loop; it's exited only when a condition is signalled */
|
/* Infinite loop; it's exited only when a condition is signalled */
|
||||||
while(1)
|
while ( 1 ) {
|
||||||
{
|
/* Write prompt */
|
||||||
/* Write prompt */
|
fputs( PROMPT, stdout );
|
||||||
fputs(PROMPT, stdout);
|
fflush( stdout );
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if(fgets(cmd, LINE_BUFFER_SIZE, stdin) == (char *)NULL ||
|
if ( fgets( cmd, LINE_BUFFER_SIZE, stdin ) == ( char* )NULL || ( tk = strtok( cmd, TOK_DELIMITERS ) ) == ( char* )NULL ) {
|
||||||
(tk = strtok(cmd, TOK_DELIMITERS)) == (char *)NULL)
|
/* New command empty; try old command */
|
||||||
{
|
if ( ( tk = strtok( old_cmd, TOK_DELIMITERS ) ) != ( char* )NULL )
|
||||||
/* New command empty; try old command */
|
if ( InvokeCommand( tk ) )
|
||||||
if((tk = strtok(old_cmd, TOK_DELIMITERS)) != (char *)NULL)
|
ChfCondition CPU_W_BAD_MONITOR_CMD, CHF_WARNING, tk ChfEnd;
|
||||||
if(InvokeCommand(tk))
|
ChfSignal();
|
||||||
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 "cpu.h"
|
||||||
#include "disk_io.h"
|
#include "disk_io.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID UTIL_CHF_MODULE_ID
|
#define CHF_MODULE_ID UTIL_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
/* Maximum size of source ROM (bytes) handled by this utility; set to
|
/* Maximum size of source ROM (bytes) handled by this utility; set to
|
||||||
a reasonable value
|
a reasonable value
|
||||||
*/
|
*/
|
||||||
#define MAX_SRC_SIZE (4*1024*1024)
|
#define MAX_SRC_SIZE ( 4 * 1024 * 1024 )
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Chf parameters - Do not change.
|
Chf parameters - Do not change.
|
||||||
The ABNORMAL_EXIT_CODE is taken from stdlib.h (EXIT_FAILURE)
|
The ABNORMAL_EXIT_CODE is taken from stdlib.h (EXIT_FAILURE)
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define CONDITION_STACK_SIZE 16
|
#define CONDITION_STACK_SIZE 16
|
||||||
#define HANDLER_STACK_SIZE 8
|
#define HANDLER_STACK_SIZE 8
|
||||||
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
||||||
|
|
||||||
/* Conditional prefix and mandatory suffix to make a message catalog
|
/* Conditional prefix and mandatory suffix to make a message catalog
|
||||||
name from cat_base_name.
|
name from cat_base_name.
|
||||||
|
@ -108,30 +106,26 @@ static char rcs_id[] = "$Id";
|
||||||
static const char cat_prefix[] = "./";
|
static const char cat_prefix[] = "./";
|
||||||
static const char cat_suffix[] = ".cat";
|
static const char cat_suffix[] = ".cat";
|
||||||
|
|
||||||
#define CAT_PREFIX_LEN (sizeof(cat_prefix)+1)
|
#define CAT_PREFIX_LEN ( sizeof( cat_prefix ) + 1 )
|
||||||
#define CAT_SUFFIX_LEN (sizeof(cat_suffix)+1)
|
#define CAT_SUFFIX_LEN ( sizeof( cat_suffix ) + 1 )
|
||||||
|
|
||||||
/* Message catalog base_name */
|
/* Message catalog base_name */
|
||||||
static const char cat_base_name[] = "saturn";
|
static const char cat_base_name[] = "saturn";
|
||||||
|
|
||||||
|
|
||||||
/* Condition codes used by this utility */
|
/* Condition codes used by this utility */
|
||||||
#define UTIL_I_PACK_USAGE 1
|
#define UTIL_I_PACK_USAGE 1
|
||||||
#define UTIL_F_PACK_CMD_LINE 2
|
#define UTIL_F_PACK_CMD_LINE 2
|
||||||
#define UTIL_F_PACK_STAT 3
|
#define UTIL_F_PACK_STAT 3
|
||||||
#define UTIL_F_PACK_SRC_SIZE 4
|
#define UTIL_F_PACK_SRC_SIZE 4
|
||||||
#define UTIL_F_PACK_MALLOC 5
|
#define UTIL_F_PACK_MALLOC 5
|
||||||
#define UTIL_F_PACK_OPEN 6
|
#define UTIL_F_PACK_OPEN 6
|
||||||
#define UTIL_F_PACK_READ 7
|
#define UTIL_F_PACK_READ 7
|
||||||
#define UTIL_F_PACK_WRITE_NIBBLES 8
|
#define UTIL_F_PACK_WRITE_NIBBLES 8
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Public functions
|
Public functions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : main
|
.title : main
|
||||||
|
@ -144,150 +138,131 @@ static const char cat_base_name[] = "saturn";
|
||||||
3.6, 2-Oct-2000, creation
|
3.6, 2-Oct-2000, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
int main(int argc, char *argv[])
|
int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
char *cat_name; /* Message catalog name */
|
char* cat_name; /* Message catalog name */
|
||||||
struct stat statb; /* stat() buffer on source file */
|
struct stat statb; /* stat() buffer on source file */
|
||||||
char *b; /* Source buffer */
|
char* b; /* Source buffer */
|
||||||
Nibble *nb; /* Nibble buffer */
|
Nibble* nb; /* Nibble buffer */
|
||||||
int d; /* Source file descriptor */
|
int d; /* Source file descriptor */
|
||||||
int i;
|
int i;
|
||||||
int st;
|
int st;
|
||||||
|
|
||||||
if((cat_name = malloc(sizeof(cat_base_name)
|
if ( ( cat_name = malloc( sizeof( cat_base_name ) + CAT_PREFIX_LEN + CAT_SUFFIX_LEN + 1 ) ) == NULL ) {
|
||||||
+CAT_PREFIX_LEN+CAT_SUFFIX_LEN+1))
|
fprintf( stderr, "Cat_name initialization failed\n" );
|
||||||
== NULL)
|
exit( ABNORMAL_EXIT_CODE );
|
||||||
{
|
|
||||||
fprintf(stderr, "Cat_name initialization failed\n");
|
|
||||||
exit(ABNORMAL_EXIT_CODE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate catalog name, without optional prefix */
|
/* Generate catalog name, without optional prefix */
|
||||||
strcpy(cat_name, cat_base_name);
|
strcpy( cat_name, cat_base_name );
|
||||||
strcat(cat_name, cat_suffix);
|
strcat( cat_name, cat_suffix );
|
||||||
|
|
||||||
/* Chf initialization with msgcat subsystem;
|
/* Chf initialization with msgcat subsystem;
|
||||||
notice that on some systems (e.g. Digital UNIX) catopen() can succeed
|
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
|
even if it was not able to open the right message catalog; better
|
||||||
try it now.
|
try it now.
|
||||||
*/
|
*/
|
||||||
if((st = ChfMsgcatInit(
|
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||||
argv[0], /* Application's name */
|
CHF_DEFAULT, /* Options */
|
||||||
CHF_DEFAULT, /* Options */
|
cat_name, /* Name of the message catalog */
|
||||||
cat_name, /* Name of the message catalog */
|
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
) ) != CHF_S_OK ||
|
||||||
)) != CHF_S_OK
|
ChfGetMessage( CHF_MODULE_ID, UTIL_I_PACK_USAGE, NULL ) == NULL ) {
|
||||||
||
|
if ( st != CHF_S_OK && st != CHF_F_CATOPEN ) {
|
||||||
ChfGetMessage(CHF_MODULE_ID, UTIL_I_PACK_USAGE, NULL) == NULL)
|
fprintf( stderr, "Chf initialization failed\n" );
|
||||||
{
|
exit( ABNORMAL_EXIT_CODE );
|
||||||
if(st != CHF_S_OK && st != CHF_F_CATOPEN)
|
}
|
||||||
{
|
|
||||||
fprintf(stderr, "Chf initialization failed\n");
|
|
||||||
exit(ABNORMAL_EXIT_CODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
fprintf( stderr, "Default message catalog open failed; trying alternate\n" );
|
||||||
fprintf(stderr,
|
|
||||||
"Default message catalog open failed; trying alternate\n");
|
|
||||||
|
|
||||||
/* Bring down Chf before initializing it again */
|
/* Bring down Chf before initializing it again */
|
||||||
if(st == CHF_S_OK) ChfExit();
|
if ( st == CHF_S_OK )
|
||||||
|
ChfExit();
|
||||||
|
|
||||||
/* Try alternate message catalog name (with prefix) */
|
/* Try alternate message catalog name (with prefix) */
|
||||||
strcpy(cat_name, cat_prefix);
|
strcpy( cat_name, cat_prefix );
|
||||||
strcat(cat_name, cat_base_name);
|
strcat( cat_name, cat_base_name );
|
||||||
strcat(cat_name, cat_suffix);
|
strcat( cat_name, cat_suffix );
|
||||||
|
|
||||||
if((st = ChfMsgcatInit(
|
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||||
argv[0], /* Application's name */
|
CHF_DEFAULT, /* Options */
|
||||||
CHF_DEFAULT, /* Options */
|
cat_name, /* Name of the message catalog */
|
||||||
cat_name, /* Name of the message catalog */
|
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
) ) != CHF_S_OK ||
|
||||||
)) != CHF_S_OK
|
ChfGetMessage( CHF_MODULE_ID, UTIL_I_PACK_USAGE, NULL ) == NULL ) {
|
||||||
||
|
fprintf( stderr, "Alternate Chf initialization failed\n" );
|
||||||
ChfGetMessage(CHF_MODULE_ID, UTIL_I_PACK_USAGE, NULL) == NULL)
|
exit( ABNORMAL_EXIT_CODE );
|
||||||
{
|
}
|
||||||
fprintf(stderr, "Alternate Chf initialization failed\n");
|
}
|
||||||
exit(ABNORMAL_EXIT_CODE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cat_name no longer needed */
|
/* cat_name no longer needed */
|
||||||
free(cat_name);
|
free( cat_name );
|
||||||
|
|
||||||
/* Now, do some useful work; pack argv[1] into argv[2] */
|
/* Now, do some useful work; pack argv[1] into argv[2] */
|
||||||
if(argc != 3)
|
if ( argc != 3 ) {
|
||||||
{
|
ChfCondition UTIL_I_PACK_USAGE, CHF_INFO ChfEnd;
|
||||||
ChfCondition UTIL_I_PACK_USAGE, CHF_INFO ChfEnd;
|
ChfCondition UTIL_F_PACK_CMD_LINE, CHF_FATAL ChfEnd;
|
||||||
ChfCondition UTIL_F_PACK_CMD_LINE, CHF_FATAL ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the size of the source file */
|
/* Get the size of the source file */
|
||||||
if(stat(argv[1], &statb))
|
if ( stat( argv[ 1 ], &statb ) ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition UTIL_F_PACK_STAT, CHF_FATAL, argv[ 1 ] ChfEnd;
|
||||||
ChfCondition UTIL_F_PACK_STAT, CHF_FATAL, argv[1] ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that actual size is reasonable */
|
/* Check that actual size is reasonable */
|
||||||
if(statb.st_size > MAX_SRC_SIZE)
|
if ( statb.st_size > MAX_SRC_SIZE ) {
|
||||||
{
|
ChfCondition UTIL_F_PACK_SRC_SIZE, CHF_FATAL, statb.st_size ChfEnd;
|
||||||
ChfCondition UTIL_F_PACK_SRC_SIZE, CHF_FATAL, statb.st_size ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate source buffer */
|
/* Allocate source buffer */
|
||||||
if((b = (char *)malloc(statb.st_size)) == (char *)NULL
|
if ( ( b = ( char* )malloc( statb.st_size ) ) == ( char* )NULL ||
|
||||||
|| (nb = (Nibble *)malloc(sizeof(Nibble) * statb.st_size))
|
( nb = ( Nibble* )malloc( sizeof( Nibble ) * statb.st_size ) ) == ( Nibble* )NULL ) {
|
||||||
== (Nibble *)NULL)
|
ChfErrnoCondition;
|
||||||
{
|
ChfCondition UTIL_F_PACK_MALLOC, CHF_FATAL, statb.st_size ChfEnd;
|
||||||
ChfErrnoCondition;
|
ChfSignal();
|
||||||
ChfCondition UTIL_F_PACK_MALLOC, CHF_FATAL, statb.st_size ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open/read/close */
|
/* open/read/close */
|
||||||
if((d = open(argv[1], O_RDONLY)) == -1)
|
if ( ( d = open( argv[ 1 ], O_RDONLY ) ) == -1 ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition UTIL_F_PACK_OPEN, CHF_FATAL, argv[ 1 ] ChfEnd;
|
||||||
ChfCondition UTIL_F_PACK_OPEN, CHF_FATAL, argv[1] ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(read(d, b, statb.st_size) != statb.st_size)
|
if ( read( d, b, statb.st_size ) != statb.st_size ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
|
||||||
|
|
||||||
(void)close(d);
|
( void )close( d );
|
||||||
|
|
||||||
ChfCondition UTIL_F_PACK_READ, CHF_FATAL, argv[1] ChfEnd;
|
ChfCondition UTIL_F_PACK_READ, CHF_FATAL, argv[ 1 ] ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)close(d);
|
( void )close( d );
|
||||||
|
|
||||||
/* Convert char -> Nibble */
|
/* Convert char -> Nibble */
|
||||||
for(i=0; i<statb.st_size; i++)
|
for ( i = 0; i < statb.st_size; i++ )
|
||||||
nb[i] = (Nibble)b[i];
|
nb[ i ] = ( Nibble )b[ i ];
|
||||||
|
|
||||||
/* Source buffer no longer needed */
|
/* Source buffer no longer needed */
|
||||||
free(b);
|
free( b );
|
||||||
|
|
||||||
/* Write */
|
/* Write */
|
||||||
if(WriteNibblesToFile(nb, statb.st_size, argv[2]))
|
if ( WriteNibblesToFile( nb, statb.st_size, argv[ 2 ] ) ) {
|
||||||
{
|
ChfCondition UTIL_F_PACK_WRITE_NIBBLES, CHF_FATAL ChfEnd;
|
||||||
ChfCondition UTIL_F_PACK_WRITE_NIBBLES, CHF_FATAL ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
560
src/romram.c
560
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 <stdlib.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h> /* access() */
|
#include <unistd.h> /* access() */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "config.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"
|
#include "args.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
/* 3.2: The rom/ram storage areas are now dynamically allocated in
|
/* 3.2: The rom/ram storage areas are now dynamically allocated in
|
||||||
a private struct ModStatus_48. The dynamic allocation is performed during
|
a private struct ModStatus_48. The dynamic allocation is performed during
|
||||||
Rom initialization, and the following macro allows us to reuse the
|
Rom initialization, and the following macro allows us to reuse the
|
||||||
existing code with minimal updates.
|
existing code with minimal updates.
|
||||||
*/
|
*/
|
||||||
static struct ModStatus_48 *mod_status_48;
|
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
|
|
||||||
|
|
||||||
|
#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.
|
module status structure, and initializes the Rom module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RomInit();
|
RomInit();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_F_ROM_INIT
|
MOD_F_ROM_INIT
|
||||||
MOD_F_MOD_STATUS_ALLOC
|
MOD_F_MOD_STATUS_ALLOC
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
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 =
|
if ( ( mod_status_48 = ( struct ModStatus_48* )malloc( sizeof( struct ModStatus_48 ) ) ) == ( struct ModStatus_48* )NULL ) {
|
||||||
(struct ModStatus_48 *)malloc(sizeof(struct ModStatus_48)))
|
ChfErrnoCondition;
|
||||||
== (struct ModStatus_48 *)NULL)
|
ChfCondition MOD_F_MOD_STATUS_ALLOC, CHF_FATAL, sizeof( struct ModStatus_48 ) ChfEnd;
|
||||||
{
|
ChfSignal();
|
||||||
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))
|
if ( ReadNibblesFromFile( args.rom_file_name, N_ROM_SIZE, mod_status_rom ) ) {
|
||||||
{
|
ChfCondition MOD_F_ROM_INIT, CHF_FATAL ChfEnd;
|
||||||
ChfCondition MOD_F_ROM_INIT, CHF_FATAL ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : RomSave
|
.title : RomSave
|
||||||
|
@ -175,22 +167,18 @@ void RomInit(void)
|
||||||
nothing.
|
nothing.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RomSave();
|
RomSave();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 11-Feb-1998, creation
|
1.1, 11-Feb-1998, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void RomSave(void)
|
void RomSave( void ) { debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomSave" ); }
|
||||||
{
|
|
||||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "RomSave");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
|
@ -202,25 +190,24 @@ void RomSave(void)
|
||||||
and returns it.
|
and returns it.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = RomRead(rel_address);
|
d = RomRead(rel_address);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
.output :
|
.output :
|
||||||
Nibble *d, datum read from memory
|
Nibble *d, datum read from memory
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 26-Jan-1998, creation
|
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
|
.title : RomWrite
|
||||||
|
@ -231,30 +218,29 @@ Nibble RomRead(Address rel_address)
|
||||||
ROM location. It signals an error condition and does nothing.
|
ROM location. It signals an error condition and does nothing.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RomWrite(rel_address, datum);
|
RomWrite(rel_address, datum);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
Nibble datum, datum to be written into memory
|
Nibble datum, datum to be written into memory
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_ROM_WRITE
|
MOD_E_ROM_WRITE
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 26-Jan-1998, creation
|
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;
|
ChfCondition MOD_E_ROM_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Main Ram module
|
Main Ram module
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
@ -266,32 +252,30 @@ void RomWrite(Address rel_address, Nibble datum)
|
||||||
This function initializes the Ram module.
|
This function initializes the Ram module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RamInit();
|
RamInit();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_W_RAM_INIT
|
MOD_W_RAM_INIT
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
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))
|
if ( ReadNibblesFromFile( args.ram_file_name, N_RAM_SIZE, mod_status_ram ) ) {
|
||||||
{
|
ChfCondition MOD_W_RAM_INIT, CHF_WARNING ChfEnd;
|
||||||
ChfCondition MOD_W_RAM_INIT, CHF_WARNING ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
|
|
||||||
(void)memset(mod_status_ram, 0, sizeof(mod_status_ram));
|
( void )memset( mod_status_ram, 0, sizeof( mod_status_ram ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : RamSave
|
.title : RamSave
|
||||||
|
@ -301,33 +285,31 @@ void RamInit(void)
|
||||||
This function saves the status of the Ram module to disk.
|
This function saves the status of the Ram module to disk.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RamSave();
|
RamSave();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_RAM_SAVE
|
MOD_E_RAM_SAVE
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 11-Feb-1998, creation
|
1.1, 11-Feb-1998, creation
|
||||||
2.4, 12-Sep-2000, update
|
2.4, 12-Sep-2000, update
|
||||||
- upon failure, added push of ChfErrnoCondition to condition stack.
|
- 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))
|
if ( WriteNibblesToFile( mod_status_ram, N_RAM_SIZE, args.ram_file_name ) ) {
|
||||||
{
|
ChfErrnoCondition;
|
||||||
ChfErrnoCondition;
|
ChfCondition MOD_E_RAM_SAVE, CHF_ERROR ChfEnd;
|
||||||
ChfCondition MOD_E_RAM_SAVE, CHF_ERROR ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : RamRead
|
.title : RamRead
|
||||||
|
@ -338,25 +320,24 @@ void RamSave(void)
|
||||||
and returns it.
|
and returns it.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = RamRead(rel_address);
|
d = RamRead(rel_address);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
.output :
|
.output :
|
||||||
Nibble *d, datum read from memory
|
Nibble *d, datum read from memory
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 26-Jan-1998, creation
|
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
|
.title : RamWrite
|
||||||
|
@ -367,28 +348,27 @@ Nibble RamRead(Address rel_address)
|
||||||
of the internal RAM.
|
of the internal RAM.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RamWrite(rel_address, datum);
|
RamWrite(rel_address, datum);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
Nibble datum, datum to be written into memory
|
Nibble datum, datum to be written into memory
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 26-Jan-1998, creation
|
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.
|
Back Switcher.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce1Init();
|
Ce1Init();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
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
|
/* Check if bank-switcher accelerators are valid; if not, initialize
|
||||||
them to a reasonable value (that is, select Port_2 bank 0).
|
them to a reasonable value (that is, select Port_2 bank 0).
|
||||||
*/
|
*/
|
||||||
if(!mod_status_hdw.accel_valid)
|
if ( !mod_status_hdw.accel_valid ) {
|
||||||
{
|
mod_status_hdw.accel_valid = 1;
|
||||||
mod_status_hdw.accel_valid = 1;
|
mod_status_hdw.accel.a48.bs_address = ( XAddress )0;
|
||||||
mod_status_hdw.accel.a48.bs_address = (XAddress)0;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : Ce1Save
|
.title : Ce1Save
|
||||||
|
@ -437,28 +415,27 @@ void Ce1Init(void)
|
||||||
This function saves the status of the Ce1 module.
|
This function saves the status of the Ce1 module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce1Save();
|
Ce1Save();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 11-Feb-1998, creation
|
1.1, 11-Feb-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
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
|
/* Nothing to be done herel the bank-switcher accelerators are saved
|
||||||
by the hdw modules
|
by the hdw modules
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : Ce1Read
|
.title : Ce1Read
|
||||||
|
@ -471,37 +448,35 @@ void Ce1Save(void)
|
||||||
most significant bits of Port_2 addresses when accessing that port.
|
most significant bits of Port_2 addresses when accessing that port.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = Ce1Read(rel_address);
|
d = Ce1Read(rel_address);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
.output :
|
.output :
|
||||||
Nibble *d, datum read from memory
|
Nibble *d, datum read from memory
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_I_BS_ADDRESS
|
MOD_I_BS_ADDRESS
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
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_TRACE, MOD_I_CALLED, "Ce1Read" );
|
||||||
debug1(DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address);
|
debug1( DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||||
|
|
||||||
/* Save the read address into the hdw accelerators.
|
/* Save the read address into the hdw accelerators.
|
||||||
bs_address can be directly or-ed with a relative port address to
|
bs_address can be directly or-ed with a relative port address to
|
||||||
obtain a valid index in Port_2
|
obtain a valid index in Port_2
|
||||||
*/
|
*/
|
||||||
#ifdef N_PORT_2_BANK
|
#ifdef N_PORT_2_BANK
|
||||||
mod_status_hdw.accel.a48.bs_address =
|
mod_status_hdw.accel.a48.bs_address = ( ( XAddress )( ( rel_address >> 1 ) & 0x1F ) << 18 ) & ( N_PORT_2_SIZE - 1 );
|
||||||
((XAddress)((rel_address >> 1) & 0x1F) << 18) & (N_PORT_2_SIZE-1);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (Nibble)0x0;
|
return ( Nibble )0x0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : Ce1Write
|
.title : Ce1Write
|
||||||
|
@ -513,31 +488,30 @@ Nibble Ce1Read(Address rel_address)
|
||||||
state of mod_status_hdw.accel.a48.bs_address is *not* changed.
|
state of mod_status_hdw.accel.a48.bs_address is *not* changed.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce1Write(rel_address, datum);
|
Ce1Write(rel_address, datum);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
Nibble datum, datum to be written into memory
|
Nibble datum, datum to be written into memory
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_CE1_WRITE
|
MOD_E_CE1_WRITE
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
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;
|
ChfCondition MOD_E_CE1_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||||
ChfSignal();
|
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.
|
This function initializes the Ce2 module, corresponding to Port 1.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce2Init();
|
Ce2Init();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_W_PORT_1_INIT
|
MOD_W_PORT_1_INIT
|
||||||
MOD_I_PORT_1_WP
|
MOD_I_PORT_1_WP
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
2.4, 11-Sep-2000, implemented
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void Ce2Init(void)
|
void Ce2Init( void )
|
||||||
{
|
{
|
||||||
Nibble new_status;
|
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,
|
if ( ReadNibblesFromFile( args.port_1_file_name, N_PORT_1_SIZE, mod_status_port_1 ) ) {
|
||||||
mod_status_port_1))
|
ChfCondition MOD_W_PORT_1_INIT, CHF_WARNING ChfEnd;
|
||||||
{
|
ChfSignal();
|
||||||
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 =
|
new_status = mod_status_hdw.card_status & ~( CE2_CARD_PRESENT | CE2_CARD_WE );
|
||||||
mod_status_hdw.card_status & ~(CE2_CARD_PRESENT|CE2_CARD_WE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Card present; check write protection */
|
||||||
/* Card present; check write protection */
|
new_status = mod_status_hdw.card_status | CE2_CARD_PRESENT;
|
||||||
new_status = mod_status_hdw.card_status | CE2_CARD_PRESENT;
|
|
||||||
|
|
||||||
if(access(args.port_1_file_name, W_OK) == 0)
|
if ( access( args.port_1_file_name, W_OK ) == 0 )
|
||||||
new_status |= CE2_CARD_WE;
|
new_status |= CE2_CARD_WE;
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
new_status &= ~CE2_CARD_WE;
|
||||||
new_status &= ~CE2_CARD_WE;
|
|
||||||
|
|
||||||
ChfErrnoCondition;
|
ChfErrnoCondition;
|
||||||
ChfCondition MOD_I_PORT_1_WP, CHF_INFO ChfEnd;
|
ChfCondition MOD_I_PORT_1_WP, CHF_INFO ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(new_status != mod_status_hdw.card_status)
|
if ( new_status != mod_status_hdw.card_status ) {
|
||||||
{
|
/* card_status changed; update, set MP bit in HST and post
|
||||||
/* card_status changed; update, set MP bit in HST and post
|
interrupt request.
|
||||||
interrupt request.
|
*/
|
||||||
*/
|
mod_status_hdw.card_status = new_status;
|
||||||
mod_status_hdw.card_status = new_status;
|
cpu_status.HST |= HST_MP_MASK;
|
||||||
cpu_status.HST |= HST_MP_MASK;
|
CpuIntRequest( INT_REQUEST_IRQ );
|
||||||
CpuIntRequest(INT_REQUEST_IRQ);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : Ce2Save
|
.title : Ce2Save
|
||||||
|
@ -621,35 +588,31 @@ void Ce2Init(void)
|
||||||
not write-protected.
|
not write-protected.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce2Save();
|
Ce2Save();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_PORT_1_SAVE
|
MOD_E_PORT_1_SAVE
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 11-Feb-1998, creation
|
1.1, 11-Feb-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
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 */
|
/* Attempt to save only if port is write-enabled */
|
||||||
if((mod_status_hdw.card_status & CE2_CARD_WE) &&
|
if ( ( mod_status_hdw.card_status & CE2_CARD_WE ) && WriteNibblesToFile( mod_status_port_1, N_PORT_1_SIZE, args.port_1_file_name ) ) {
|
||||||
WriteNibblesToFile(mod_status_port_1, N_PORT_1_SIZE,
|
ChfErrnoCondition;
|
||||||
args.port_1_file_name))
|
ChfCondition MOD_E_PORT_1_SAVE, CHF_ERROR ChfEnd;
|
||||||
{
|
ChfSignal();
|
||||||
ChfErrnoCondition;
|
|
||||||
ChfCondition MOD_E_PORT_1_SAVE, CHF_ERROR ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : Ce2Read
|
.title : Ce2Read
|
||||||
|
@ -659,26 +622,25 @@ void Ce2Save(void)
|
||||||
This function reads a nibble from the Ce2 module.
|
This function reads a nibble from the Ce2 module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = Ce2Read(rel_address)
|
d = Ce2Read(rel_address)
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
.output :
|
.output :
|
||||||
Nibble *d, datum read from memory
|
Nibble *d, datum read from memory
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
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
|
.title : Ce2Write
|
||||||
|
@ -688,29 +650,28 @@ Nibble Ce2Read(Address rel_address)
|
||||||
This function writes a nibble to the Ce2 module.
|
This function writes a nibble to the Ce2 module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce2Write(rel_address, datum);
|
Ce2Write(rel_address, datum);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
Nibble datum, datum to be written into memory
|
Nibble datum, datum to be written into memory
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
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.
|
(bank switched) port 2.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
NCe3Init();
|
NCe3Init();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_W_PORT_2_INIT
|
MOD_W_PORT_2_INIT
|
||||||
MOD_I_PORT_2_WP
|
MOD_I_PORT_2_WP
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
2.4, 11-Sep-2000, implemented
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
void NCe3Init(void)
|
void NCe3Init( void )
|
||||||
{
|
{
|
||||||
Nibble new_status;
|
Nibble new_status;
|
||||||
|
|
||||||
debug1(DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Init");
|
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Init" );
|
||||||
|
|
||||||
#ifdef N_PORT_2_BANK
|
#ifdef N_PORT_2_BANK
|
||||||
if(ReadNibblesFromFile(args.port_2_file_name, N_PORT_2_SIZE,
|
if ( ReadNibblesFromFile( args.port_2_file_name, N_PORT_2_SIZE, mod_status_port_2 ) ) {
|
||||||
mod_status_port_2))
|
ChfCondition MOD_W_PORT_2_INIT, CHF_WARNING ChfEnd;
|
||||||
{
|
ChfSignal();
|
||||||
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 =
|
new_status = mod_status_hdw.card_status & ~( NCE3_CARD_PRESENT | NCE3_CARD_WE );
|
||||||
mod_status_hdw.card_status & ~(NCE3_CARD_PRESENT|NCE3_CARD_WE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Card present; check write protection */
|
||||||
/* Card present; check write protection */
|
new_status = mod_status_hdw.card_status | NCE3_CARD_PRESENT;
|
||||||
new_status = mod_status_hdw.card_status | NCE3_CARD_PRESENT;
|
|
||||||
|
|
||||||
if(access(args.port_2_file_name, W_OK) == 0)
|
if ( access( args.port_2_file_name, W_OK ) == 0 )
|
||||||
new_status |= NCE3_CARD_WE;
|
new_status |= NCE3_CARD_WE;
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
new_status &= ~NCE3_CARD_WE;
|
||||||
new_status &= ~NCE3_CARD_WE;
|
|
||||||
|
|
||||||
ChfErrnoCondition;
|
ChfErrnoCondition;
|
||||||
ChfCondition MOD_I_PORT_2_WP, CHF_INFO ChfEnd;
|
ChfCondition MOD_I_PORT_2_WP, CHF_INFO ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* If N_PORT_2_BANK is undefined, Port 2 is not emulated */
|
/* If N_PORT_2_BANK is undefined, Port 2 is not emulated */
|
||||||
new_status =
|
new_status = mod_status_hdw.card_status & ~( NCE3_CARD_PRESENT | NCE3_CARD_WE );
|
||||||
mod_status_hdw.card_status & ~(NCE3_CARD_PRESENT|NCE3_CARD_WE);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(new_status != mod_status_hdw.card_status)
|
if ( new_status != mod_status_hdw.card_status ) {
|
||||||
{
|
/* card_status changed; update, set MP bit in HST and post
|
||||||
/* card_status changed; update, set MP bit in HST and post
|
interrupt request.
|
||||||
interrupt request.
|
*/
|
||||||
*/
|
mod_status_hdw.card_status = new_status;
|
||||||
mod_status_hdw.card_status = new_status;
|
cpu_status.HST |= HST_MP_MASK;
|
||||||
cpu_status.HST |= HST_MP_MASK;
|
CpuIntRequest( INT_REQUEST_IRQ );
|
||||||
CpuIntRequest(INT_REQUEST_IRQ);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : NCe3Save
|
.title : NCe3Save
|
||||||
|
@ -802,37 +755,33 @@ void NCe3Init(void)
|
||||||
This function saves the status of the NCe3 module.
|
This function saves the status of the NCe3 module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
NCe3Save();
|
NCe3Save();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_PORT_2_SAVE
|
MOD_E_PORT_2_SAVE
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 11-Feb-1998, creation
|
1.1, 11-Feb-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
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
|
#ifdef N_PORT_2_BANK
|
||||||
/* Attempt to save only if port is write-enabled */
|
/* Attempt to save only if port is write-enabled */
|
||||||
if((mod_status_hdw.card_status & NCE3_CARD_WE) &&
|
if ( ( mod_status_hdw.card_status & NCE3_CARD_WE ) && WriteNibblesToFile( mod_status_port_2, N_PORT_2_SIZE, args.port_2_file_name ) ) {
|
||||||
WriteNibblesToFile(mod_status_port_2, N_PORT_2_SIZE,
|
ChfErrnoCondition;
|
||||||
args.port_2_file_name))
|
ChfCondition MOD_E_PORT_2_SAVE, CHF_ERROR ChfEnd;
|
||||||
{
|
ChfSignal();
|
||||||
ChfErrnoCondition;
|
|
||||||
ChfCondition MOD_E_PORT_2_SAVE, CHF_ERROR ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : NCe3Read
|
.title : NCe3Read
|
||||||
|
@ -842,37 +791,35 @@ void NCe3Save(void)
|
||||||
This function reads a nibble from the NCe3 module.
|
This function reads a nibble from the NCe3 module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = NCe3Read(rel_address)
|
d = NCe3Read(rel_address)
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
.output :
|
.output :
|
||||||
Nibble *d, datum read from memory
|
Nibble *d, datum read from memory
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_NCE3_READ
|
MOD_E_NCE3_READ
|
||||||
|
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
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
|
#ifdef N_PORT_2_BANK
|
||||||
return
|
return mod_status_port_2[ rel_address | mod_status_hdw.accel.a48.bs_address ];
|
||||||
mod_status_port_2[rel_address | mod_status_hdw.accel.a48.bs_address];
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
ChfCondition MOD_E_NCE3_READ, CHF_ERROR, rel_address ChfEnd;
|
ChfCondition MOD_E_NCE3_READ, CHF_ERROR, rel_address ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
return (Nibble)0;
|
return ( Nibble )0;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : NCe3Write
|
.title : NCe3Write
|
||||||
|
@ -883,28 +830,27 @@ Nibble NCe3Read(Address rel_address)
|
||||||
it is not currently implemented.
|
it is not currently implemented.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
NCe3Write(rel_address, datum);
|
NCe3Write(rel_address, datum);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
Nibble datum, datum to be written into memory
|
Nibble datum, datum to be written into memory
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_NCE3_WRITE
|
MOD_E_NCE3_WRITE
|
||||||
|
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 23-Jan-1998, creation
|
1.1, 23-Jan-1998, creation
|
||||||
2.4, 11-Sep-2000, implemented
|
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
|
#ifdef N_PORT_2_BANK
|
||||||
mod_status_port_2[rel_address | mod_status_hdw.accel.a48.bs_address]
|
mod_status_port_2[ rel_address | mod_status_hdw.accel.a48.bs_address ] = datum;
|
||||||
= datum;
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
ChfCondition MOD_E_NCE3_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
ChfCondition MOD_E_NCE3_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||||
|
|
452
src/romram49.c
452
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 <stdlib.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h> /* access() */
|
#include <unistd.h> /* access() */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "config.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"
|
#include "args.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
#define FLASH_VIEW_SELECTOR 0x40000
|
||||||
|
#define FLASH_BANK_MASK 0x3FFFF
|
||||||
|
|
||||||
#define FLASH_VIEW_SELECTOR 0x40000
|
#define CE2_RAM_OFFSET 0x80000
|
||||||
#define FLASH_BANK_MASK 0x3FFFF
|
#define NCE3_RAM_OFFSET 0xC0000
|
||||||
|
#define NCE3_RAM_MASK 0x3FFFF
|
||||||
|
|
||||||
#define CE2_RAM_OFFSET 0x80000
|
#define HDW_LCR_OFFSET 0x1C
|
||||||
#define NCE3_RAM_OFFSET 0xC0000
|
#define LCR_LED 0x8
|
||||||
#define NCE3_RAM_MASK 0x3FFFF
|
|
||||||
|
|
||||||
#define HDW_LCR_OFFSET 0x1C
|
|
||||||
#define LCR_LED 0x8
|
|
||||||
|
|
||||||
/* 3.3: This is no longer static, because flash49.c needs access to
|
/* 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,
|
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.
|
module status structure, and initializes the Flash Rom module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RomInit49();
|
RomInit49();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_F_ROM_INIT
|
MOD_F_ROM_INIT
|
||||||
MOD_F_MOD_STATUS_ALLOC
|
MOD_F_MOD_STATUS_ALLOC
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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 =
|
if ( ( mod_status_49 = ( struct ModStatus_49* )malloc( sizeof( struct ModStatus_49 ) ) ) == ( struct ModStatus_49* )NULL ) {
|
||||||
(struct ModStatus_49 *)malloc(sizeof(struct ModStatus_49)))
|
ChfErrnoCondition;
|
||||||
== (struct ModStatus_49 *)NULL)
|
ChfCondition MOD_F_MOD_STATUS_ALLOC, CHF_FATAL, sizeof( struct ModStatus_49 ) ChfEnd;
|
||||||
{
|
ChfSignal();
|
||||||
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,
|
if ( ReadNibblesFromFile( args.rom_file_name, N_FLASH_SIZE_49, mod_status_49->flash ) ) {
|
||||||
mod_status_49->flash))
|
ChfCondition MOD_F_ROM_INIT, CHF_FATAL ChfEnd;
|
||||||
{
|
ChfSignal();
|
||||||
ChfCondition MOD_F_ROM_INIT, CHF_FATAL ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : RomSave49
|
.title : RomSave49
|
||||||
|
@ -190,33 +181,30 @@ void RomInit49(void)
|
||||||
This function saves the status of the Flash Rom.
|
This function saves the status of the Flash Rom.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RomSave49();
|
RomSave49();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_ROM_SAVE
|
MOD_E_ROM_SAVE
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
3.2, 21-Sep-2000, creation
|
||||||
3.3, 25-Sep-2000, implemented
|
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,
|
if ( WriteNibblesToFile( mod_status_49->flash, N_FLASH_SIZE_49, args.rom_file_name ) ) {
|
||||||
args.rom_file_name))
|
ChfErrnoCondition;
|
||||||
{
|
ChfCondition MOD_E_ROM_SAVE, CHF_ERROR ChfEnd;
|
||||||
ChfErrnoCondition;
|
ChfSignal();
|
||||||
ChfCondition MOD_E_ROM_SAVE, CHF_ERROR ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : RomRead49
|
.title : RomRead49
|
||||||
|
@ -227,30 +215,28 @@ void RomSave49(void)
|
||||||
'rel_address' and returns it.
|
'rel_address' and returns it.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = RomRead49(rel_address);
|
d = RomRead49(rel_address);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
.output :
|
.output :
|
||||||
Nibble *d, datum read from memory
|
Nibble *d, datum read from memory
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
3.2, 21-Sep-2000, creation
|
||||||
|
|
||||||
.- */
|
.- */
|
||||||
Nibble RomRead49(Address rel_address)
|
Nibble RomRead49( Address rel_address )
|
||||||
{
|
{
|
||||||
register XAddress view;
|
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[
|
view = mod_status.hdw.accel.a49.view[ ( rel_address & FLASH_VIEW_SELECTOR ) != 0 ];
|
||||||
(rel_address & FLASH_VIEW_SELECTOR) != 0];
|
|
||||||
|
|
||||||
return mod_status_49->flash[view | (rel_address & FLASH_BANK_MASK)];
|
return mod_status_49->flash[ view | ( rel_address & FLASH_BANK_MASK ) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : RomWrite49
|
.title : RomWrite49
|
||||||
|
@ -266,31 +252,30 @@ Nibble RomRead49(Address rel_address)
|
||||||
Those cycles are silently ignored.
|
Those cycles are silently ignored.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RomWrite49(rel_address, datum);
|
RomWrite49(rel_address, datum);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
Nibble datum, datum to be written into memory
|
Nibble datum, datum to be written into memory
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
3.2, 21-Sep-2000, creation
|
||||||
3.3, 26-Sep-2000, implemented
|
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
|
/* Ignore write cycles through ROM controller; HP49 ROM 1.19-4
|
||||||
can do this when to ON key is pressed.
|
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.
|
This function initializes the Ram module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RamInit49();
|
RamInit49();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_W_RAM_INIT
|
MOD_W_RAM_INIT
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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,
|
if ( ReadNibblesFromFile( args.ram_file_name, N_RAM_SIZE_49, mod_status_49->ram ) ) {
|
||||||
mod_status_49->ram))
|
ChfCondition MOD_W_RAM_INIT, CHF_WARNING ChfEnd;
|
||||||
{
|
ChfSignal();
|
||||||
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
|
.title : RamSave49
|
||||||
|
@ -338,32 +320,29 @@ void RamInit49(void)
|
||||||
This function saves the status of the Ram module to disk.
|
This function saves the status of the Ram module to disk.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RamSave49();
|
RamSave49();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_E_RAM_SAVE
|
MOD_E_RAM_SAVE
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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,
|
if ( WriteNibblesToFile( mod_status_49->ram, N_RAM_SIZE_49, args.ram_file_name ) ) {
|
||||||
args.ram_file_name))
|
ChfErrnoCondition;
|
||||||
{
|
ChfCondition MOD_E_RAM_SAVE, CHF_ERROR ChfEnd;
|
||||||
ChfErrnoCondition;
|
ChfSignal();
|
||||||
ChfCondition MOD_E_RAM_SAVE, CHF_ERROR ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : RamRead49
|
.title : RamRead49
|
||||||
|
@ -374,25 +353,24 @@ void RamSave49(void)
|
||||||
and returns it.
|
and returns it.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = RamRead49(rel_address);
|
d = RamRead49(rel_address);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
.output :
|
.output :
|
||||||
Nibble *d, datum read from memory
|
Nibble *d, datum read from memory
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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
|
.title : RamWrite49
|
||||||
|
@ -403,28 +381,27 @@ Nibble RamRead49(Address rel_address)
|
||||||
of the internal RAM.
|
of the internal RAM.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
RamWrite49(rel_address, datum);
|
RamWrite49(rel_address, datum);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
Nibble datum, datum to be written into memory
|
Nibble datum, datum to be written into memory
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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.
|
Back Switcher.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce1Init49();
|
Ce1Init49();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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
|
/* Check if bank-switcher accelerators are valid; if not, initialize
|
||||||
them to a reasonable value (that is, select Flash Rom bank 0 for
|
them to a reasonable value (that is, select Flash Rom bank 0 for
|
||||||
both views).
|
both views).
|
||||||
*/
|
*/
|
||||||
if(!mod_status.hdw.accel_valid)
|
if ( !mod_status.hdw.accel_valid ) {
|
||||||
{
|
mod_status.hdw.accel_valid = 1;
|
||||||
mod_status.hdw.accel_valid = 1;
|
mod_status.hdw.accel.a49.view[ 0 ] = mod_status.hdw.accel.a49.view[ 1 ] = ( XAddress )0;
|
||||||
mod_status.hdw.accel.a49.view[0] =
|
|
||||||
mod_status.hdw.accel.a49.view[1] = (XAddress)0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : Ce1Save49
|
.title : Ce1Save49
|
||||||
|
@ -474,40 +448,36 @@ void Ce1Init49(void)
|
||||||
This function saves the status of the Ce1 module.
|
This function saves the status of the Ce1 module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce1Save49();
|
Ce1Save49();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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
|
/* Nothing to be done here; the bank-switcher accelerators are saved
|
||||||
by the hdw modules
|
by the hdw modules
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This fragment of code is used by both Ce1Read49() and Ce1Write49();
|
/* 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
|
the macro definition is here to allow us to write the code once and
|
||||||
use it many times without incurring a function call overhead.
|
use it many times without incurring a function call overhead.
|
||||||
*/
|
*/
|
||||||
#define Ce1SetViews \
|
#define Ce1SetViews \
|
||||||
{ \
|
{ \
|
||||||
mod_status.hdw.accel.a49.view[0] = \
|
mod_status.hdw.accel.a49.view[ 0 ] = ( ( XAddress )( ( rel_address >> 5 ) & 0x03 ) << 18 ); \
|
||||||
((XAddress)((rel_address >> 5) & 0x03) << 18); \
|
\
|
||||||
\
|
mod_status.hdw.accel.a49.view[ 1 ] = ( ( XAddress )( ( rel_address >> 1 ) & 0x0F ) << 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.
|
most significant bits of addresses when accessing Flash Rom.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = Ce1Read49(rel_address);
|
d = Ce1Read49(rel_address);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
.output :
|
.output :
|
||||||
Nibble *d, datum read from memory
|
Nibble *d, datum read from memory
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_I_BS_ADDRESS
|
MOD_I_BS_ADDRESS
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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_TRACE, MOD_I_CALLED, "Ce1Read49" );
|
||||||
debug1(DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address);
|
debug1( DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||||
|
|
||||||
/* Save the ROM view base addresses address into the hdw accelerators.
|
/* Save the ROM view base addresses address into the hdw accelerators.
|
||||||
view[] can be directly or-ed with a relative port address to
|
view[] can be directly or-ed with a relative port address to
|
||||||
obtain a valid index in Flash Rom.
|
obtain a valid index in Flash Rom.
|
||||||
*/
|
*/
|
||||||
Ce1SetViews;
|
Ce1SetViews;
|
||||||
|
|
||||||
return (Nibble)0x0;
|
return ( Nibble )0x0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : Ce1Write49
|
.title : Ce1Write49
|
||||||
|
@ -562,34 +531,33 @@ Nibble Ce1Read49(Address rel_address)
|
||||||
most significant bits of addresses when accessing Flash Rom.
|
most significant bits of addresses when accessing Flash Rom.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce1Write49(rel_address, datum);
|
Ce1Write49(rel_address, datum);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
Nibble datum, datum to be written into memory; ignored
|
Nibble datum, datum to be written into memory; ignored
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
MOD_I_BS_ADDRESS
|
MOD_I_BS_ADDRESS
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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_TRACE, MOD_I_CALLED, "Ce1Write49" );
|
||||||
debug1(DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address);
|
debug1( DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||||
|
|
||||||
/* Save the ROM view base addresses address into the hdw accelerators.
|
/* Save the ROM view base addresses address into the hdw accelerators.
|
||||||
view[] can be directly or-ed with a relative port address to
|
view[] can be directly or-ed with a relative port address to
|
||||||
obtain a valid index in Flash Rom.
|
obtain a valid index in Flash Rom.
|
||||||
*/
|
*/
|
||||||
Ce1SetViews;
|
Ce1SetViews;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Ce2 module
|
Ce2 module
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
@ -602,13 +570,13 @@ void Ce1Write49(Address rel_address, Nibble datum)
|
||||||
the first bank of ERAM.
|
the first bank of ERAM.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce2Init49();
|
Ce2Init49();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
3.2, 21-Sep-2000, creation
|
||||||
3.4, 27-Sep-2000, update:
|
3.4, 27-Sep-2000, update:
|
||||||
|
@ -616,15 +584,15 @@ void Ce1Write49(Address rel_address, Nibble datum)
|
||||||
HP39/40 firmware.
|
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 */
|
/* Set base of ce2 area */
|
||||||
mod_status_49->ce2 = mod_status_49->ram + CE2_RAM_OFFSET;
|
mod_status_49->ce2 = mod_status_49->ram + CE2_RAM_OFFSET;
|
||||||
|
|
||||||
/* CE2 always present and write enabled */
|
/* 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
|
#if 0
|
||||||
/* card_status changed; update, set MP bit in HST and post
|
/* card_status changed; update, set MP bit in HST and post
|
||||||
|
@ -635,7 +603,6 @@ void Ce2Init49(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : Ce2Save49
|
.title : Ce2Save49
|
||||||
|
@ -645,25 +612,24 @@ void Ce2Init49(void)
|
||||||
This function saves the status of the Ce2 module.
|
This function saves the status of the Ce2 module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce2Save49();
|
Ce2Save49();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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() */
|
/* Do nothing; the whole RAM is saved by RamSave49() */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : Ce2Read49
|
.title : Ce2Read49
|
||||||
|
@ -673,25 +639,24 @@ void Ce2Save49(void)
|
||||||
This function reads a nibble from the Ce2 module.
|
This function reads a nibble from the Ce2 module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = Ce2Read49(rel_address)
|
d = Ce2Read49(rel_address)
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
.output :
|
.output :
|
||||||
Nibble *d, datum read from memory
|
Nibble *d, datum read from memory
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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
|
.title : Ce2Write49
|
||||||
|
@ -701,28 +666,27 @@ Nibble Ce2Read49(Address rel_address)
|
||||||
This function writes a nibble to the Ce2 module.
|
This function writes a nibble to the Ce2 module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
Ce2Write49(rel_address, datum);
|
Ce2Write49(rel_address, datum);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address
|
Address rel_address, memory address
|
||||||
Nibble datum, datum to be written into memory
|
Nibble datum, datum to be written into memory
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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.
|
the first bank of ERAM.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
NCe3Init49();
|
NCe3Init49();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
3.2, 21-Sep-2000, creation
|
||||||
3.4, 27-Sep-2000, update:
|
3.4, 27-Sep-2000, update:
|
||||||
|
@ -749,15 +713,15 @@ void Ce2Write49(Address rel_address, Nibble datum)
|
||||||
HP39/40 firmware.
|
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 */
|
/* Set base of nce3 area */
|
||||||
mod_status_49->nce3 = mod_status_49->ram + NCE3_RAM_OFFSET;
|
mod_status_49->nce3 = mod_status_49->ram + NCE3_RAM_OFFSET;
|
||||||
|
|
||||||
/* NCE3 always present and write enabled */
|
/* 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
|
#if 0
|
||||||
/* card_status changed; update, set MP bit in HST and post
|
/* card_status changed; update, set MP bit in HST and post
|
||||||
|
@ -768,7 +732,6 @@ void NCe3Init49(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : NCe3Save49
|
.title : NCe3Save49
|
||||||
|
@ -778,25 +741,24 @@ void NCe3Init49(void)
|
||||||
This function saves the status of the NCe3 module.
|
This function saves the status of the NCe3 module.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
NCe3Save49();
|
NCe3Save49();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
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() */
|
/* Do nothing; the whole RAM is saved by RamSave49() */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : NCe3Read49
|
.title : NCe3Read49
|
||||||
|
@ -814,33 +776,29 @@ void NCe3Save49(void)
|
||||||
the ABSOLUTE address of the memory access.
|
the ABSOLUTE address of the memory access.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
d = NCe3Read49(rel_address)
|
d = NCe3Read49(rel_address)
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address (ABSOLUTE)
|
Address rel_address, memory address (ABSOLUTE)
|
||||||
.output :
|
.output :
|
||||||
Nibble *d, datum read from memory
|
Nibble *d, datum read from memory
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
3.2, 21-Sep-2000, creation
|
||||||
3.3, 25-Sep-2000, update
|
3.3, 25-Sep-2000, update
|
||||||
- added vectors into flash49 for FlashROM read ops
|
- 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
|
return ( mod_status.hdw.hdw[ HDW_LCR_OFFSET ] & LCR_LED )
|
||||||
(mod_status.hdw.hdw[HDW_LCR_OFFSET] & LCR_LED)
|
? FlashRead49( mod_status.hdw.accel.a49.view[ ( rel_address & FLASH_VIEW_SELECTOR ) != 0 ] |
|
||||||
? FlashRead49(
|
( rel_address & FLASH_BANK_MASK ) )
|
||||||
mod_status.hdw.accel.a49.view[
|
: mod_status_49->nce3[ rel_address & NCE3_RAM_MASK ];
|
||||||
(rel_address & FLASH_VIEW_SELECTOR) != 0]
|
|
||||||
| (rel_address & FLASH_BANK_MASK))
|
|
||||||
: mod_status_49->nce3[rel_address & NCE3_RAM_MASK];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : NCe3Write49
|
.title : NCe3Write49
|
||||||
|
@ -859,29 +817,27 @@ Nibble NCe3Read49(Address rel_address)
|
||||||
|
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
NCe3Write49(rel_address, datum);
|
NCe3Write49(rel_address, datum);
|
||||||
.input :
|
.input :
|
||||||
Address rel_address, memory address (ABSOLUTE)
|
Address rel_address, memory address (ABSOLUTE)
|
||||||
Nibble datum, datum to be written into memory
|
Nibble datum, datum to be written into memory
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
MOD_I_CALLED
|
MOD_I_CALLED
|
||||||
.notes :
|
.notes :
|
||||||
3.2, 21-Sep-2000, creation
|
3.2, 21-Sep-2000, creation
|
||||||
3.3, 25-Sep-2000, update
|
3.3, 25-Sep-2000, update
|
||||||
- added vectors into flash49 for FlashROM write ops
|
- 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)
|
if ( mod_status.hdw.hdw[ HDW_LCR_OFFSET ] & LCR_LED )
|
||||||
FlashWrite49(mod_status.hdw.accel.a49.view[
|
FlashWrite49( mod_status.hdw.accel.a49.view[ ( rel_address & FLASH_VIEW_SELECTOR ) != 0 ] | ( rel_address & FLASH_BANK_MASK ),
|
||||||
(rel_address & FLASH_VIEW_SELECTOR) != 0]
|
datum );
|
||||||
| (rel_address & FLASH_BANK_MASK),
|
|
||||||
datum);
|
|
||||||
else
|
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_CALLED 101 /* Function %s called */
|
||||||
#define SERIAL_I_REVISION 102 /* Serial port emulation rev. %s */
|
#define SERIAL_I_REVISION 102 /* Serial port emulation rev. %s */
|
||||||
#define SERIAL_I_READ 103 /* Read %s -> %x */
|
#define SERIAL_I_READ 103 /* Read %s -> %x */
|
||||||
#define SERIAL_I_WRITE 104 /* Write %s %x -> %x */
|
#define SERIAL_I_WRITE 104 /* Write %s %x -> %x */
|
||||||
#define SERIAL_I_RBR 105 /* Read RBR -> %x */
|
#define SERIAL_I_RBR 105 /* Read RBR -> %x */
|
||||||
#define SERIAL_I_TBR 106 /* Write TBR <- %x */
|
#define SERIAL_I_TBR 106 /* Write TBR <- %x */
|
||||||
#define SERIAL_I_PTY_NAME 107 /* Slave pty name is %s */
|
#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_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_FULL_TRB 202 /* Write into full TX buffer, tcs=%x */
|
||||||
#define SERIAL_W_NOPTY 203 /* 3.16: Pty support not available */
|
#define SERIAL_W_NOPTY 203 /* 3.16: Pty support not available */
|
||||||
#define SERIAL_E_TRB_DRAIN 301 /* Error draining TX buffer */
|
#define SERIAL_E_TRB_DRAIN 301 /* Error draining TX buffer */
|
||||||
#define SERIAL_E_RRB_CHARGE 302 /* Error charging RX buffer */
|
#define SERIAL_E_RRB_CHARGE 302 /* Error charging RX buffer */
|
||||||
#define SERIAL_E_PTY_CLOSE 303 /* Error closing pty */
|
#define SERIAL_E_PTY_CLOSE 303 /* Error closing pty */
|
||||||
#define SERIAL_F_OPENPTY 401 /* openpty() failed on master pty */
|
#define SERIAL_F_OPENPTY 401 /* openpty() failed on master pty */
|
||||||
#define SERIAL_F_FCNTL 402 /* fcntl() 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_OPEN_MASTER 403 /* Can't open pty master %s */
|
||||||
#define SERIAL_F_GRANTPT 404 /* grantpt() failed on master pty */
|
#define SERIAL_F_GRANTPT 404 /* grantpt() failed on master pty */
|
||||||
#define SERIAL_F_UNLOCKPT 405 /* unlockpt() 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_OPEN_SLAVE 406 /* Can't open pty slave %s */
|
||||||
#define SERIAL_F_PUSH 407 /* ioctl(I_PUSH,%s) failed on slave */
|
#define SERIAL_F_PUSH 407 /* ioctl(I_PUSH,%s) failed on slave */
|
||||||
#define SERIAL_F_TCGETATTR 408 /* tcgetattr() failed on master */
|
#define SERIAL_F_TCGETATTR 408 /* tcgetattr() failed on master */
|
||||||
#define SERIAL_F_TCSETATTR 409 /* tcsetattr() failed on master */
|
#define SERIAL_F_TCSETATTR 409 /* tcsetattr() failed on master */
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Function prototypes
|
Function prototypes
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
const char *SerialInit(void);
|
const char* SerialInit( void );
|
||||||
void SerialClose(void);
|
void SerialClose( void );
|
||||||
|
|
||||||
/* Information about slave side of pty */
|
/* Information about slave side of pty */
|
||||||
const char *SerialPtyName(void);
|
const char* SerialPtyName( void );
|
||||||
|
|
||||||
/* Register read */
|
/* Register read */
|
||||||
Nibble Serial_IOC_Read(void);
|
Nibble Serial_IOC_Read( void );
|
||||||
Nibble Serial_RCS_Read(void);
|
Nibble Serial_RCS_Read( void );
|
||||||
Nibble Serial_TCS_Read(void);
|
Nibble Serial_TCS_Read( void );
|
||||||
int8 Serial_RBR_Read(void);
|
int8 Serial_RBR_Read( void );
|
||||||
|
|
||||||
/* Register write */
|
/* Register write */
|
||||||
void Serial_IOC_Write(Nibble n);
|
void Serial_IOC_Write( Nibble n );
|
||||||
void Serial_RCS_Write(Nibble n);
|
void Serial_RCS_Write( Nibble n );
|
||||||
void Serial_TCS_Write(Nibble n);
|
void Serial_TCS_Write( Nibble n );
|
||||||
void Serial_CRER_Write(Nibble n);
|
void Serial_CRER_Write( Nibble n );
|
||||||
void Serial_TBR_Write(int8 d);
|
void Serial_TBR_Write( int8 d );
|
||||||
|
|
||||||
/* Event handling */
|
/* Event handling */
|
||||||
void HandleSerial(void);
|
void HandleSerial( void );
|
||||||
|
|
717
src/t48.c
717
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 "args.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define CHF_MODULE_ID X11_CHF_MODULE_ID
|
#define CHF_MODULE_ID X11_CHF_MODULE_ID
|
||||||
#include <Chf.h>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Chf parameters - Do not change.
|
Chf parameters - Do not change.
|
||||||
The ABNORMAL_EXIT_CODE is taken from stdlib.h (EXIT_FAILURE)
|
The ABNORMAL_EXIT_CODE is taken from stdlib.h (EXIT_FAILURE)
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define MAIN_MSGCAT_NAME "t48.cat"
|
#define MAIN_MSGCAT_NAME "t48.cat"
|
||||||
#define CONDITION_STACK_SIZE 16
|
#define CONDITION_STACK_SIZE 16
|
||||||
#define HANDLER_STACK_SIZE 8
|
#define HANDLER_STACK_SIZE 8
|
||||||
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
#define ABNORMAL_EXIT_CODE EXIT_FAILURE
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Other parameters
|
Other parameters
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define APP_CLASS "T48"
|
#define APP_CLASS "T48"
|
||||||
#define LCD_BACKGROUND "green"
|
#define LCD_BACKGROUND "green"
|
||||||
#define LCD_FOREGROUND "black"
|
#define LCD_FOREGROUND "black"
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Private variables
|
Private variables
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static XtAppContext app_context;
|
static XtAppContext app_context;
|
||||||
static Widget shell_widget;
|
static Widget shell_widget;
|
||||||
|
|
||||||
/* Command line options descriptor */
|
/* Command line options descriptor */
|
||||||
XrmOptionDescRec options[] =
|
XrmOptionDescRec options[] = {
|
||||||
{
|
/* option, specifier, argKind, value */
|
||||||
/* option, specifier, argKind, value */
|
{ "-reset", "*reset", XrmoptionNoArg, "True" },
|
||||||
{ "-reset", "*reset", XrmoptionNoArg, "True" },
|
{ "-monitor", "*monitor", XrmoptionNoArg, "True" },
|
||||||
{ "-monitor", "*monitor", XrmoptionNoArg, "True" },
|
{ "-path", "*path", XrmoptionSepArg },
|
||||||
{ "-path", "*path", XrmoptionSepArg },
|
{ "-cpu", "*cpu", XrmoptionSepArg },
|
||||||
{ "-cpu", "*cpu", XrmoptionSepArg },
|
{ "-mod", "*mod", XrmoptionSepArg },
|
||||||
{ "-mod", "*mod", XrmoptionSepArg },
|
{ "-hdw", "*hdw", XrmoptionSepArg },
|
||||||
{ "-hdw", "*hdw", XrmoptionSepArg },
|
{ "-rom", "*rom", XrmoptionSepArg },
|
||||||
{ "-rom", "*rom", XrmoptionSepArg },
|
{ "-ram", "*ram", XrmoptionSepArg },
|
||||||
{ "-ram", "*ram", XrmoptionSepArg },
|
{ "-port1", "*port1", XrmoptionSepArg },
|
||||||
{ "-port1", "*port1", XrmoptionSepArg },
|
{ "-port2", "*port2", XrmoptionSepArg }
|
||||||
{ "-port2", "*port2", XrmoptionSepArg }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_OPTIONS (sizeof(options)/sizeof(XrmOptionDescRec))
|
#define NUM_OPTIONS ( sizeof( options ) / sizeof( XrmOptionDescRec ) )
|
||||||
|
|
||||||
|
|
||||||
/* Application fallback resources */
|
/* Application fallback resources */
|
||||||
String fallback_resources[] =
|
String fallback_resources[] = {
|
||||||
{
|
NULL /* Null terminated */
|
||||||
NULL /* Null terminated */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Application options container */
|
/* Application options container */
|
||||||
struct app_opt
|
struct app_opt {
|
||||||
{
|
Boolean reset;
|
||||||
Boolean reset;
|
Boolean monitor;
|
||||||
Boolean monitor;
|
Pixel fg_pix;
|
||||||
Pixel fg_pix;
|
Pixel bg_pix;
|
||||||
Pixel bg_pix;
|
String path;
|
||||||
String path;
|
String cpu;
|
||||||
String cpu;
|
String mod;
|
||||||
String mod;
|
String hdw;
|
||||||
String hdw;
|
String rom;
|
||||||
String rom;
|
String ram;
|
||||||
String ram;
|
String port1;
|
||||||
String port1;
|
String port2;
|
||||||
String port2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Application resources/options descriptor */
|
/* Application resources/options descriptor */
|
||||||
XtResource app_res[] =
|
XtResource app_res[] = {
|
||||||
{
|
{"foreground", "Foreground", XtRPixel, sizeof( Pixel ), XtOffsetOf( struct app_opt, fg_pix ), XtRString, LCD_FOREGROUND},
|
||||||
{ "foreground", "Foreground",
|
{"background", "Background", XtRPixel, sizeof( Pixel ), XtOffsetOf( struct app_opt, bg_pix ), XtRString, LCD_BACKGROUND},
|
||||||
XtRPixel, sizeof(Pixel), XtOffsetOf(struct app_opt, fg_pix),
|
{"reset", "Reset", XtRBoolean, sizeof( Boolean ), XtOffsetOf( struct app_opt, reset ), XtRString, "False" },
|
||||||
XtRString, LCD_FOREGROUND
|
{"monitor", "Monitor", XtRBoolean, sizeof( Boolean ), XtOffsetOf( struct app_opt, monitor ), XtRString, "False" },
|
||||||
},
|
{"path", "Path", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, path ), XtRString, "." },
|
||||||
{ "background", "Background",
|
{"cpu", "Cpu", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, cpu ), XtRString, "cpu" },
|
||||||
XtRPixel, sizeof(Pixel), XtOffsetOf(struct app_opt, bg_pix),
|
{"mod", "Mod", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, mod ), XtRString, "mod" },
|
||||||
XtRString, LCD_BACKGROUND
|
{"hdw", "Hdw", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, hdw ), XtRString, "hdw" },
|
||||||
},
|
{"rom", "Rom", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, rom ), XtRString, "rom" },
|
||||||
{ "reset", "Reset",
|
{"ram", "Ram", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, ram ), XtRString, "ram" },
|
||||||
XtRBoolean, sizeof(Boolean), XtOffsetOf(struct app_opt, reset),
|
{"port1", "Port1", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, port1 ), XtRString, "port1" },
|
||||||
XtRString, "False"
|
{"port2", "Port2", XtRString, sizeof( String ), XtOffsetOf( struct app_opt, port2 ), XtRString, "port2" }
|
||||||
},
|
|
||||||
{ "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 */
|
/* Emulator options */
|
||||||
struct Args args;
|
struct Args args;
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Private functions
|
Private functions
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* KeySym -> HP48 'enum Key' translator */
|
/* KeySym -> HP48 'enum Key' translator */
|
||||||
static enum Key Ks2K(KeySym ks)
|
static enum Key Ks2K( KeySym ks )
|
||||||
{
|
{
|
||||||
switch(ks)
|
switch ( ks ) {
|
||||||
{
|
/* Backspace */
|
||||||
/* Backspace */
|
case XK_BackSpace:
|
||||||
case XK_BackSpace: return KEY_BKSP;
|
return KEY_BKSP;
|
||||||
|
|
||||||
/* Delete */
|
/* Delete */
|
||||||
case XK_Delete: return KEY_DEL;
|
case XK_Delete:
|
||||||
case XK_KP_Delete: return KEY_DEL;
|
return KEY_DEL;
|
||||||
|
case XK_KP_Delete:
|
||||||
|
return KEY_DEL;
|
||||||
|
|
||||||
/* Enter */
|
/* Enter */
|
||||||
case XK_KP_Enter: return KEY_ENTER;
|
case XK_KP_Enter:
|
||||||
case XK_Return: return KEY_ENTER;
|
return KEY_ENTER;
|
||||||
|
case XK_Return:
|
||||||
|
return KEY_ENTER;
|
||||||
|
|
||||||
/* Cursor keys */
|
/* Cursor keys */
|
||||||
case XK_KP_Left: return KEY_LEFT;
|
case XK_KP_Left:
|
||||||
case XK_Left: return KEY_LEFT;
|
return KEY_LEFT;
|
||||||
|
case XK_Left:
|
||||||
|
return KEY_LEFT;
|
||||||
|
|
||||||
case XK_KP_Right: return KEY_RIGHT;
|
case XK_KP_Right:
|
||||||
case XK_Right: return KEY_RIGHT;
|
return KEY_RIGHT;
|
||||||
|
case XK_Right:
|
||||||
|
return KEY_RIGHT;
|
||||||
|
|
||||||
case XK_KP_Up: return KEY_UP;
|
case XK_KP_Up:
|
||||||
case XK_Up: return KEY_UP;
|
return KEY_UP;
|
||||||
|
case XK_Up:
|
||||||
|
return KEY_UP;
|
||||||
|
|
||||||
case XK_KP_Down: return KEY_DOWN;
|
case XK_KP_Down:
|
||||||
case XK_Down: return KEY_DOWN;
|
return KEY_DOWN;
|
||||||
|
case XK_Down:
|
||||||
|
return KEY_DOWN;
|
||||||
|
|
||||||
/* Function keys */
|
/* Function keys */
|
||||||
case XK_F1: return KEY_F1;
|
case XK_F1:
|
||||||
case XK_F2: return KEY_F2;
|
return KEY_F1;
|
||||||
case XK_F3: return KEY_F3;
|
case XK_F2:
|
||||||
case XK_F4: return KEY_F4;
|
return KEY_F2;
|
||||||
case XK_F5: return KEY_F5;
|
case XK_F3:
|
||||||
case XK_F6: return KEY_F6;
|
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 */
|
/* Shift L, R, Alpha, ON */
|
||||||
case XK_Shift_L: return KEY_SH_L;
|
case XK_Shift_L:
|
||||||
case XK_Shift_R: return KEY_SH_R;
|
return KEY_SH_L;
|
||||||
case XK_Alt_L: return KEY_ALPHA;
|
case XK_Shift_R:
|
||||||
case XK_Alt_R: return KEY_ALPHA;
|
return KEY_SH_R;
|
||||||
case XK_Escape: return KEY_ON;
|
case XK_Alt_L:
|
||||||
|
return KEY_ALPHA;
|
||||||
|
case XK_Alt_R:
|
||||||
|
return KEY_ALPHA;
|
||||||
|
case XK_Escape:
|
||||||
|
return KEY_ON;
|
||||||
|
|
||||||
/* Numeric keypad and surroundings */
|
/* Numeric keypad and surroundings */
|
||||||
case XK_KP_0: return KEY_0;
|
case XK_KP_0:
|
||||||
case XK_KP_1: return KEY_1;
|
return KEY_0;
|
||||||
case XK_KP_2: return KEY_2;
|
case XK_KP_1:
|
||||||
case XK_KP_3: return KEY_3;
|
return KEY_1;
|
||||||
case XK_KP_4: return KEY_4;
|
case XK_KP_2:
|
||||||
case XK_KP_5: return KEY_5;
|
return KEY_2;
|
||||||
case XK_KP_6: return KEY_6;
|
case XK_KP_3:
|
||||||
case XK_KP_7: return KEY_7;
|
return KEY_3;
|
||||||
case XK_KP_8: return KEY_8;
|
case XK_KP_4:
|
||||||
case XK_KP_9: return KEY_9;
|
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_KP_Add:
|
||||||
case XK_plus: return KEY_ADD;
|
return KEY_ADD;
|
||||||
|
case XK_plus:
|
||||||
|
return KEY_ADD;
|
||||||
|
|
||||||
case XK_KP_Subtract: return KEY_SUB;
|
case XK_KP_Subtract:
|
||||||
case XK_minus: return KEY_SUB;
|
return KEY_SUB;
|
||||||
|
case XK_minus:
|
||||||
|
return KEY_SUB;
|
||||||
|
|
||||||
case XK_KP_Multiply: return KEY_MUL;
|
case XK_KP_Multiply:
|
||||||
case XK_asterisk: return KEY_MUL;
|
return KEY_MUL;
|
||||||
|
case XK_asterisk:
|
||||||
|
return KEY_MUL;
|
||||||
|
|
||||||
case XK_KP_Divide: return KEY_DIV;
|
case XK_KP_Divide:
|
||||||
case XK_slash: return KEY_DIV;
|
return KEY_DIV;
|
||||||
|
case XK_slash:
|
||||||
|
return KEY_DIV;
|
||||||
|
|
||||||
case XK_KP_Space: return KEY_SPC;
|
case XK_KP_Space:
|
||||||
case XK_space: return KEY_SPC;
|
return KEY_SPC;
|
||||||
|
case XK_space:
|
||||||
|
return KEY_SPC;
|
||||||
|
|
||||||
/* Upper half of the keyboard */
|
/* Upper half of the keyboard */
|
||||||
case XK_1: return KEY_MTH;
|
case XK_1:
|
||||||
case XK_2: return KEY_PRG;
|
return KEY_MTH;
|
||||||
case XK_3: return KEY_CST;
|
case XK_2:
|
||||||
case XK_4: return KEY_VAR;
|
return KEY_PRG;
|
||||||
case XK_5: return KEY_UP;
|
case XK_3:
|
||||||
case XK_6: return KEY_NXT;
|
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_q:
|
||||||
case XK_w: return KEY_STO;
|
return KEY_AP;
|
||||||
case XK_e: return KEY_EVAL;
|
case XK_w:
|
||||||
case XK_r: return KEY_LEFT;
|
return KEY_STO;
|
||||||
case XK_t: return KEY_DOWN;
|
case XK_e:
|
||||||
case XK_y: return KEY_RIGHT;
|
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_a:
|
||||||
case XK_s: return KEY_COS;
|
return KEY_SIN;
|
||||||
case XK_d: return KEY_TAN;
|
case XK_s:
|
||||||
case XK_f: return KEY_SQRT;
|
return KEY_COS;
|
||||||
case XK_g: return KEY_POWER;
|
case XK_d:
|
||||||
case XK_h: return KEY_INV;
|
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_z:
|
||||||
case XK_x: return KEY_ENTER;
|
return KEY_ENTER;
|
||||||
case XK_c: return KEY_CHS;
|
case XK_x:
|
||||||
case XK_v: return KEY_EEX;
|
return KEY_ENTER;
|
||||||
case XK_b: return KEY_DEL;
|
case XK_c:
|
||||||
case XK_n: return KEY_BKSP;
|
return KEY_CHS;
|
||||||
|
case XK_v:
|
||||||
|
return KEY_EEX;
|
||||||
|
case XK_b:
|
||||||
|
return KEY_DEL;
|
||||||
|
case XK_n:
|
||||||
|
return KEY_BKSP;
|
||||||
|
|
||||||
/* Other useful aliases */
|
/* Other useful aliases */
|
||||||
case XK_Tab: return KEY_NXT;
|
case XK_Tab:
|
||||||
case XK_apostrophe: return KEY_AP;
|
return KEY_NXT;
|
||||||
case XK_period: return KEY_DOT;
|
case XK_apostrophe:
|
||||||
|
return KEY_AP;
|
||||||
|
case XK_period:
|
||||||
|
return KEY_DOT;
|
||||||
|
|
||||||
/* Save */
|
/* Save */
|
||||||
case XK_Control_L:
|
case XK_Control_L:
|
||||||
ModSave();
|
ModSave();
|
||||||
CpuSave();
|
CpuSave();
|
||||||
exit(0);
|
exit( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return KEY_NULL;
|
return KEY_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* X Event handler, called by the X Toolkit when appropriate */
|
/* X Event handler, called by the X Toolkit when appropriate */
|
||||||
static void XEventHandler(Widget w, XtPointer cl_data, XEvent *ev,
|
static void XEventHandler( Widget w, XtPointer cl_data, XEvent* ev, Boolean* cont )
|
||||||
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 */
|
/* Continue to dispatch */
|
||||||
*cont = True;
|
*cont = True;
|
||||||
|
|
||||||
if(ev->type == Expose)
|
if ( ev->type == Expose ) {
|
||||||
{
|
debug1( DEBUG_C_X11, X11_I_LCD_EXPOSE, ev->xexpose.count );
|
||||||
debug1(DEBUG_C_X11, X11_I_LCD_EXPOSE, ev->xexpose.count);
|
if ( ev->xexpose.count == 0 )
|
||||||
if(ev->xexpose.count == 0) RefreshLcd();
|
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(ev->type = KeyRelease)
|
else if ( ev->type == KeyPress || ev->type == KeyRelease ) {
|
||||||
{
|
( void )XLookupString( ( XKeyEvent* )ev, ( char* )NULL, 0, &ks, ( XComposeStatus* )NULL );
|
||||||
debug1(DEBUG_C_X11, X11_I_KEY_RELEASE, ks);
|
|
||||||
KeybRelease(Ks2K(ks));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
if ( ev->type == KeyPress ) {
|
||||||
{
|
debug1( DEBUG_C_X11, X11_I_KEY_PRESS, ks );
|
||||||
/* Unknown X Event - discard */
|
KeybPress( Ks2K( ks ) );
|
||||||
debug1(DEBUG_C_X11, X11_I_X_EVENT, ev->type);
|
}
|
||||||
}
|
|
||||||
|
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 */
|
/* 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);
|
strcpy( s, path );
|
||||||
return s;
|
strcat( s, "/" );
|
||||||
|
strcat( s, name );
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the X interface */
|
/* 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;
|
unsigned long fg_pix, bg_pix;
|
||||||
XSetWindowAttributes attr;
|
XSetWindowAttributes attr;
|
||||||
Arg xt_args[20];
|
Arg xt_args[ 20 ];
|
||||||
int n;
|
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 */
|
/* Setup Arg vector for shell widget creation */
|
||||||
n = 0;
|
n = 0;
|
||||||
XtSetArg(xt_args[n], XtNwidth, 131*2+2*8); n++;
|
XtSetArg( xt_args[ n ], XtNwidth, 131 * 2 + 2 * 8 );
|
||||||
XtSetArg(xt_args[n], XtNminWidth, 131*2+2*8); n++;
|
n++;
|
||||||
XtSetArg(xt_args[n], XtNmaxWidth, 131*2+2*8); n++;
|
XtSetArg( xt_args[ n ], XtNminWidth, 131 * 2 + 2 * 8 );
|
||||||
XtSetArg(xt_args[n], XtNheight, 64*2+28); n++;
|
n++;
|
||||||
XtSetArg(xt_args[n], XtNminHeight, 64*2+28); n++;
|
XtSetArg( xt_args[ n ], XtNmaxWidth, 131 * 2 + 2 * 8 );
|
||||||
XtSetArg(xt_args[n], XtNmaxHeight, 64*2+28); n++;
|
n++;
|
||||||
XtSetArg(xt_args[n], XtNx, 0); n++;
|
XtSetArg( xt_args[ n ], XtNheight, 64 * 2 + 28 );
|
||||||
XtSetArg(xt_args[n], XtNy, 0); n++;
|
n++;
|
||||||
XtSetArg(xt_args[n], XtNinput, True); 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,
|
/* Initialize application, parse command line options,
|
||||||
create its main shell.
|
create its main shell.
|
||||||
*/
|
*/
|
||||||
shell_widget = XtAppInitialize(
|
shell_widget = XtAppInitialize( &app_context, APP_CLASS, options, NUM_OPTIONS, &argc, argv, fallback_resources, xt_args, n );
|
||||||
&app_context,
|
|
||||||
APP_CLASS,
|
|
||||||
options, NUM_OPTIONS,
|
|
||||||
&argc, argv,
|
|
||||||
fallback_resources,
|
|
||||||
xt_args, n
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Check unknown options - argv[0] always contains program name */
|
/* Check unknown options - argv[0] always contains program name */
|
||||||
if(argc > 1)
|
if ( argc > 1 ) {
|
||||||
{
|
int i;
|
||||||
int i;
|
for ( i = 1; i < argc; i++ )
|
||||||
for(i=1; i<argc; i++)
|
ChfCondition X11_E_BAD_OPTION, CHF_ERROR, argv[ i ] ChfEnd;
|
||||||
ChfCondition X11_E_BAD_OPTION, CHF_ERROR, argv[i] ChfEnd;
|
|
||||||
|
|
||||||
ChfCondition X11_I_USAGE, CHF_INFO, argv[0] ChfEnd;
|
ChfCondition X11_I_USAGE, CHF_INFO, argv[ 0 ] ChfEnd;
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get application options and fill the 'struct app_opt opt' structure */
|
/* Get application options and fill the 'struct app_opt opt' structure */
|
||||||
XtGetApplicationResources(
|
XtGetApplicationResources( shell_widget, ( XtPointer )opt, app_res, NUM_APP_RES, ( ArgList )NULL, ( Cardinal )0 );
|
||||||
shell_widget,
|
|
||||||
(XtPointer)opt,
|
|
||||||
app_res,
|
|
||||||
NUM_APP_RES,
|
|
||||||
(ArgList)NULL,
|
|
||||||
(Cardinal)0
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Add private event handler for the main shell */
|
/* Add private event handler for the main shell */
|
||||||
XtAddEventHandler(
|
XtAddEventHandler( shell_widget, KeyPressMask | KeyReleaseMask | ExposureMask, False, /* Don't call with non-maskable events */
|
||||||
shell_widget,
|
XEventHandler, ( XtPointer )NULL );
|
||||||
KeyPressMask|KeyReleaseMask|ExposureMask,
|
|
||||||
False, /* Don't call with non-maskable events */
|
|
||||||
XEventHandler,
|
|
||||||
(XtPointer)NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Realize shell widget */
|
/* Realize shell widget */
|
||||||
XtRealizeWidget(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.
|
It must handle the X Events relevant for the application.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
HandleXEvents();
|
HandleXEvents();
|
||||||
.input :
|
.input :
|
||||||
void
|
void
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
X11_I_CALLED
|
X11_I_CALLED
|
||||||
X11_I_LCD_EXPOSE
|
X11_I_LCD_EXPOSE
|
||||||
X11_I_KEY_PRESS
|
X11_I_KEY_PRESS
|
||||||
X11_I_KEY_RELEASE
|
X11_I_KEY_RELEASE
|
||||||
X11_I_X_EVENT
|
X11_I_X_EVENT
|
||||||
.notes :
|
.notes :
|
||||||
1.1, 19-Feb-1998, creation
|
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.
|
/* If there is at least one event pending, process the first event.
|
||||||
NOTE: This is an IF instead of a WHILE for two reasons:
|
NOTE: This is an IF instead of a WHILE for two reasons:
|
||||||
|
|
||||||
- to be sure that X Events related to the keyboard interface are
|
- to be sure that X Events related to the keyboard interface are
|
||||||
actually 'seen' by the HP48, since the current keyboard emulator
|
actually 'seen' by the HP48, since the current keyboard emulator
|
||||||
has no key memory.
|
has no key memory.
|
||||||
|
|
||||||
- this function will be called again very soon, so the Events queue
|
- this function will be called again very soon, so the Events queue
|
||||||
will not starve anyway.
|
will not starve anyway.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(XtAppPending(app_context))
|
if ( XtAppPending( app_context ) )
|
||||||
XtAppProcessEvent(app_context, XtIMAll);
|
XtAppProcessEvent( app_context, XtIMAll );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* .+
|
/* .+
|
||||||
|
|
||||||
.title : main
|
.title : main
|
||||||
|
@ -531,66 +534,60 @@ void HandleXEvents(void)
|
||||||
1.1, 19-Feb-1998, creation
|
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 */
|
/* Chf initialization with msgcat subsystem */
|
||||||
if(ChfMsgcatInit(
|
if ( ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||||
argv[0], /* Application's name */
|
CHF_DEFAULT, /* Options */
|
||||||
CHF_DEFAULT, /* Options */
|
MAIN_MSGCAT_NAME, /* Name of the message catalog */
|
||||||
MAIN_MSGCAT_NAME, /* Name of the message catalog */
|
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
||||||
ABNORMAL_EXIT_CODE /* Abnormal exit code */
|
) != CHF_S_OK ) {
|
||||||
) != CHF_S_OK)
|
fprintf( stderr, "Chf initialization failed\n" );
|
||||||
{
|
exit( ABNORMAL_EXIT_CODE );
|
||||||
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 */
|
/* Initialize X */
|
||||||
InitializeX(argc, argv, &opt);
|
InitializeX( argc, argv, &opt );
|
||||||
|
|
||||||
/* Initialize LCD window */
|
/* Initialize LCD window */
|
||||||
InitLcd(XtDisplay(shell_widget), XtWindow(shell_widget),
|
InitLcd( XtDisplay( shell_widget ), XtWindow( shell_widget ), opt.fg_pix, opt.bg_pix );
|
||||||
opt.fg_pix, opt.bg_pix);
|
|
||||||
|
|
||||||
/* Fill the emulator options data structure */
|
/* Fill the emulator options data structure */
|
||||||
args.cpu_file_name = GetPathname(opt.path, opt.cpu);
|
args.cpu_file_name = GetPathname( opt.path, opt.cpu );
|
||||||
args.mod_file_name = GetPathname(opt.path, opt.mod);
|
args.mod_file_name = GetPathname( opt.path, opt.mod );
|
||||||
args.hdw_file_name = GetPathname(opt.path, opt.hdw);
|
args.hdw_file_name = GetPathname( opt.path, opt.hdw );
|
||||||
args.rom_file_name = GetPathname(opt.path, opt.rom);
|
args.rom_file_name = GetPathname( opt.path, opt.rom );
|
||||||
args.ram_file_name = GetPathname(opt.path, opt.ram);
|
args.ram_file_name = GetPathname( opt.path, opt.ram );
|
||||||
args.port_1_file_name = GetPathname(opt.path, opt.port1);
|
args.port_1_file_name = GetPathname( opt.path, opt.port1 );
|
||||||
args.port_2_file_name = GetPathname(opt.path, opt.port2);
|
args.port_2_file_name = GetPathname( opt.path, opt.port2 );
|
||||||
|
|
||||||
/* Initialize peripheral modules */
|
/* Initialize peripheral modules */
|
||||||
ModInit();
|
ModInit();
|
||||||
|
|
||||||
/* Initialize peripheral modules */
|
/* Initialize peripheral modules */
|
||||||
CpuInit();
|
CpuInit();
|
||||||
|
|
||||||
/* Reset the system, if required */
|
/* Reset the system, if required */
|
||||||
if(opt.reset)
|
if ( opt.reset ) {
|
||||||
{
|
ModReset();
|
||||||
ModReset();
|
CpuReset();
|
||||||
CpuReset();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(opt.monitor)
|
if ( opt.monitor ) {
|
||||||
{
|
/* Call Monitor */
|
||||||
/* Call Monitor */
|
Monitor();
|
||||||
Monitor();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Call Emulator directly */
|
||||||
/* Call Emulator directly */
|
Emulator();
|
||||||
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 $"
|
#define X11_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||||
|
|
||||||
|
|
||||||
typedef void (*FsbContinuation)(int proceed, char *file_name);
|
|
||||||
|
|
||||||
|
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_CALLED 101 /* Function %s called */
|
||||||
#define X11_I_LCD_PAR 102 /* LCD Parameter %s: %x */
|
#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_LCD_EXPOSE 103 /* LCD X Expose event, count=%d */
|
||||||
#define X11_I_KEY_PRESS 104 /* 2.1: Pressed key %s */
|
#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_KEY_RELEASE 105 /* 2.1: Released key %s */
|
||||||
#define X11_I_REVISION 107 /* X11 interface revision: %s */
|
#define X11_I_REVISION 107 /* X11 interface revision: %s */
|
||||||
#define X11_I_USAGE 108 /* Usage %s: ... */
|
#define X11_I_USAGE 108 /* Usage %s: ... */
|
||||||
#define X11_I_FACE 109 /* Selected face %s */
|
#define X11_I_FACE 109 /* Selected face %s */
|
||||||
#define X11_I_NKEYS 110 /* The face has %d keys */
|
#define X11_I_NKEYS 110 /* The face has %d keys */
|
||||||
#define X11_I_KEY 111 /* Creating key %d, inOut %s */
|
#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_FOUND_CS 112 /* Found cs widget %s, value %s */
|
||||||
#define X11_I_HIER 113 /* Traversing widget %s */
|
#define X11_I_HIER 113 /* Traversing widget %s */
|
||||||
#define X11_I_HIER_NC 114 /* Current widget has %d children */
|
#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_BAD_ACTION_CALL 201 /* Xt Action called with %d args */
|
||||||
#define X11_W_UNKNOWN_ATOM 202 /* X Atom %s unknown */
|
#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_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_W_TOO_MANY_MSG 204 /* 3.15: Too many messages (max %d) */
|
||||||
#define X11_E_BAD_OPTION 301 /* Invalid option: %s */
|
#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_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_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_X_ERROR 401 /* X Window System fatal error */
|
||||||
#define X11_F_NO_KEYS 402 /* 3.15: Face has no keys */
|
#define X11_F_NO_KEYS 402 /* 3.15: Face has no keys */
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Function prototypes
|
Function prototypes
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void HandleXEvents(void);
|
void HandleXEvents( void );
|
||||||
void IdleXLoop(unsigned long max_wait);
|
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 <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h> /* Main X header */
|
#include <X11/Xlib.h> /* Main X header */
|
||||||
#include <X11/Intrinsic.h> /* Main Xt header */
|
#include <X11/Intrinsic.h> /* Main Xt header */
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "machdep.h"
|
#include "machdep.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
#include "disk_io.h"
|
#include "disk_io.h"
|
||||||
#include "x11.h" /* ActivateFSB() */
|
#include "x11.h" /* ActivateFSB() */
|
||||||
#include "x_func.h"
|
#include "x_func.h"
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
#include "debug.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>
|
#include <Chf.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Private functions: CPU access
|
Private functions: CPU access
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Return the A field of a DataRegister as an integer. */
|
/* Return the A field of a DataRegister as an integer. */
|
||||||
static int R2int(const Nibble *r)
|
static int R2int( const Nibble* r )
|
||||||
{
|
{
|
||||||
return(
|
return ( ( ( int )r[ 0 ] ) | ( ( int )r[ 1 ] << 4 ) | ( ( int )r[ 2 ] << 8 ) | ( ( int )r[ 3 ] << 12 ) | ( ( int )r[ 4 ] << 16 ) );
|
||||||
((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.
|
/* Return the contents of the byte pointed by addr.
|
||||||
Memory is accessed through ReadNibble()
|
Memory is accessed through ReadNibble()
|
||||||
*/
|
*/
|
||||||
static int ByteFromAddress(Address addr)
|
static int ByteFromAddress( Address addr ) { return ( int )ReadNibble( addr ) + ( int )ReadNibble( addr + 1 ) * 16; }
|
||||||
{
|
|
||||||
return (int)ReadNibble(addr) + (int)ReadNibble(addr+1) * 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Return a dynamically-allocated copy of the contents of the IDNT
|
/* Return a dynamically-allocated copy of the contents of the IDNT
|
||||||
object pointed by D1. D1 points to the *body* of the
|
object pointed by D1. D1 points to the *body* of the
|
||||||
RPL object, that is, to the IDNT length byte directly and *not*
|
RPL object, that is, to the IDNT length byte directly and *not*
|
||||||
to the prologue.
|
to the prologue.
|
||||||
*/
|
*/
|
||||||
static char *NameFromD1(void)
|
static char* NameFromD1( void )
|
||||||
{
|
{
|
||||||
Address addr = cpu_status.D1; /* Points to the IDNT body */
|
Address addr = cpu_status.D1; /* Points to the IDNT body */
|
||||||
int len = ByteFromAddress(addr); /* IDNT length */
|
int len = ByteFromAddress( addr ); /* IDNT length */
|
||||||
char *name = XtMalloc(len+1); /* IDNT name buffer */
|
char* name = XtMalloc( len + 1 ); /* IDNT name buffer */
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
/* Read the name; toascii() is there to avoid 'strange' characters */
|
/* Read the name; toascii() is there to avoid 'strange' characters */
|
||||||
for(c=0; c<len; c++)
|
for ( c = 0; c < len; c++ ) {
|
||||||
{
|
addr += 2;
|
||||||
addr += 2;
|
name[ c ] = ( char )toascii( ByteFromAddress( addr ) );
|
||||||
name[c] = (char)toascii(ByteFromAddress(addr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
name[c] = '\0'; /* Terminate and return the name */
|
name[ c ] = '\0'; /* Terminate and return the name */
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Private functions: action routines
|
Private functions: action routines
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Set the emulator speed to the given value (in MHz); the desired speed
|
/* 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.
|
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
|
#ifndef REAL_CPU_SPEED
|
||||||
ChfCondition X_FUNC_E_NO_SPEED, CHF_ERROR ChfEnd;
|
ChfCondition X_FUNC_E_NO_SPEED, CHF_ERROR ChfEnd;
|
||||||
|
@ -183,149 +166,131 @@ static void SetSpeed(Nibble function_code)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
int new_speed;
|
int new_speed;
|
||||||
|
|
||||||
/* Get new_speed from A field of C register */
|
/* Get new_speed from A field of C register */
|
||||||
new_speed = R2int(cpu_status.C);
|
new_speed = R2int( cpu_status.C );
|
||||||
|
|
||||||
/* Compute inner loop limit; 4 is the real CPU speed in MHz when
|
/* Compute inner loop limit; 4 is the real CPU speed in MHz when
|
||||||
the limit is set to INNER_LOOP_MAX. No overflow checks,
|
the limit is set to INNER_LOOP_MAX. No overflow checks,
|
||||||
because new_speed is >=0, has an architectural upper limit of 2^20,
|
because new_speed is >=0, has an architectural upper limit of 2^20,
|
||||||
and int are at least 2^31.
|
and int are at least 2^31.
|
||||||
*/
|
*/
|
||||||
cpu_status.inner_loop_max = (new_speed * INNER_LOOP_MAX) / 4;
|
cpu_status.inner_loop_max = ( new_speed * INNER_LOOP_MAX ) / 4;
|
||||||
|
|
||||||
/* Notify the user about the speed change */
|
/* Notify the user about the speed change */
|
||||||
if(cpu_status.inner_loop_max)
|
if ( cpu_status.inner_loop_max )
|
||||||
ChfCondition X_FUNC_I_SET_SPEED, CHF_INFO, new_speed ChfEnd;
|
ChfCondition X_FUNC_I_SET_SPEED, CHF_INFO, new_speed ChfEnd;
|
||||||
|
|
||||||
else
|
else
|
||||||
ChfCondition X_FUNC_I_MAX_SPEED, CHF_INFO ChfEnd;
|
ChfCondition X_FUNC_I_MAX_SPEED, CHF_INFO ChfEnd;
|
||||||
|
|
||||||
ChfSignal();
|
ChfSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* This array holds the binary headers for all known hw configurations;
|
/* This array holds the binary headers for all known hw configurations;
|
||||||
here, '?' is a wildcard character when reading from file
|
here, '?' is a wildcard character when reading from file
|
||||||
(see ReadObjectFromFile()) and is replaced by 'S' when writing
|
(see ReadObjectFromFile()) and is replaced by 'S' when writing
|
||||||
to file (see WriteObjectToFile()).
|
to file (see WriteObjectToFile()).
|
||||||
*/
|
*/
|
||||||
struct BinHdrMapping
|
struct BinHdrMapping {
|
||||||
{
|
char* hw;
|
||||||
char *hw;
|
char* hdr;
|
||||||
char *hdr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct BinHdrMapping bin_hdr_mapping[] =
|
static const struct BinHdrMapping bin_hdr_mapping[] = {
|
||||||
{
|
{"hp48", "HPHP48-?"},
|
||||||
{ "hp48", "HPHP48-?" },
|
{"hp49", "HPHP49-?"}
|
||||||
{ "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 the header of binary files for current hw configuration;
|
||||||
return NULL if the header cannot be determined. In the latter case,
|
return NULL if the header cannot be determined. In the latter case,
|
||||||
generate an appropriate condition.
|
generate an appropriate condition.
|
||||||
*/
|
*/
|
||||||
static const char *BinaryHeader(void)
|
static const char* BinaryHeader( void )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i=0; i<N_BIN_HDR_MAPPING; i++)
|
for ( i = 0; i < N_BIN_HDR_MAPPING; i++ )
|
||||||
if(strcmp(args.hw, bin_hdr_mapping[i].hw) == 0)
|
if ( strcmp( args.hw, bin_hdr_mapping[ i ].hw ) == 0 )
|
||||||
return bin_hdr_mapping[i].hdr;
|
return bin_hdr_mapping[ i ].hdr;
|
||||||
|
|
||||||
ChfCondition X_FUNC_E_NO_BIN_HDR, CHF_ERROR, args.hw ChfEnd;
|
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
|
/* This function is the continuation of Kget(); it is invoked when the
|
||||||
user interaction with the FSB ends.
|
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 */
|
/* Check whether continuation should proceed */
|
||||||
if(!proceed)
|
if ( !proceed ) {
|
||||||
{
|
ChfCondition X_FUNC_W_ABORTED, CHF_WARNING ChfEnd;
|
||||||
ChfCondition X_FUNC_W_ABORTED, CHF_WARNING ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Ok to proceed; read:
|
||||||
/* Ok to proceed; read:
|
- target start address from A[A]
|
||||||
- target start address from A[A]
|
- target end address from C[A]
|
||||||
- target end address from C[A]
|
- binary header with BinaryHeader()
|
||||||
- binary header with BinaryHeader()
|
*/
|
||||||
*/
|
int start_addr = R2int( cpu_status.A );
|
||||||
int start_addr = R2int(cpu_status.A);
|
int end_addr = R2int( cpu_status.C );
|
||||||
int end_addr = R2int(cpu_status.C);
|
const char* bin_hdr = BinaryHeader();
|
||||||
const char *bin_hdr = BinaryHeader();
|
|
||||||
|
|
||||||
debug1(DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name);
|
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);
|
debug3( DEBUG_C_X_FUNC, X_FUNC_I_KGET, start_addr, end_addr, bin_hdr );
|
||||||
|
|
||||||
if(bin_hdr == (const char *)NULL
|
if ( bin_hdr == ( const char* )NULL || ReadObjectFromFile( file_name, bin_hdr, ( Address )start_addr, ( Address )end_addr ) ) {
|
||||||
|| ReadObjectFromFile(file_name, bin_hdr, (Address)start_addr,
|
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||||
(Address)end_addr))
|
ChfSignal();
|
||||||
{
|
}
|
||||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuRunRequest();
|
CpuRunRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function is the continuation of Send(); it is invoked when the
|
/* This function is the continuation of Send(); it is invoked when the
|
||||||
user interaction with the FSB ends.
|
user interaction with the FSB ends.
|
||||||
*/
|
*/
|
||||||
static void SendContinuation(int proceed, char *file_name)
|
static void SendContinuation( int proceed, char* file_name )
|
||||||
{
|
{
|
||||||
if(!proceed)
|
if ( !proceed ) {
|
||||||
{
|
ChfCondition X_FUNC_W_ABORTED, CHF_WARNING ChfEnd;
|
||||||
ChfCondition X_FUNC_W_ABORTED, CHF_WARNING ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Ok to proceed; read:
|
||||||
/* Ok to proceed; read:
|
- source start address from A[A]
|
||||||
- source start address from A[A]
|
- source end address from C[A]
|
||||||
- source end address from C[A]
|
- binary header with BinaryHeader()
|
||||||
- binary header with BinaryHeader()
|
*/
|
||||||
*/
|
int start_addr = R2int( cpu_status.A );
|
||||||
int start_addr = R2int(cpu_status.A);
|
int end_addr = R2int( cpu_status.C );
|
||||||
int end_addr = R2int(cpu_status.C);
|
const char* bin_hdr = BinaryHeader();
|
||||||
const char *bin_hdr = BinaryHeader();
|
|
||||||
|
|
||||||
debug1(DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name);
|
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);
|
debug3( DEBUG_C_X_FUNC, X_FUNC_I_SEND, start_addr, end_addr, bin_hdr );
|
||||||
|
|
||||||
if(bin_hdr == (const char *)NULL
|
if ( bin_hdr == ( const char* )NULL || WriteObjectToFile( ( Address )start_addr, ( Address )end_addr, bin_hdr, file_name ) ) {
|
||||||
|| WriteObjectToFile((Address)start_addr,
|
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||||
(Address)end_addr, bin_hdr, file_name))
|
ChfSignal();
|
||||||
{
|
}
|
||||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuRunRequest();
|
CpuRunRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function does the setup of a transfer, performing the following
|
/* This function does the setup of a transfer, performing the following
|
||||||
actions:
|
actions:
|
||||||
|
|
||||||
|
@ -336,137 +301,117 @@ static void SendContinuation(int proceed, char *file_name)
|
||||||
be invoked when the user interaction ends
|
be invoked when the user interaction ends
|
||||||
- Halts the CPU
|
- Halts the CPU
|
||||||
*/
|
*/
|
||||||
static void SetupXfer(
|
static void SetupXfer( int msg, const char* def_msg, FsbContinuation cont )
|
||||||
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())
|
if ( CpuHaltAllowed() ) {
|
||||||
{
|
char* fsb_title = XtNewString( ChfGetMessage( CHF_MODULE_ID, msg, def_msg ) );
|
||||||
char *fsb_title =
|
|
||||||
XtNewString(ChfGetMessage(CHF_MODULE_ID, msg, def_msg));
|
|
||||||
|
|
||||||
char *fsb_file =
|
char* fsb_file = NameFromD1();
|
||||||
NameFromD1();
|
|
||||||
|
|
||||||
ActivateFSB(fsb_title, fsb_file, cont);
|
ActivateFSB( fsb_title, fsb_file, cont );
|
||||||
|
|
||||||
/* Free *before* CpuHaltRequest() because it does not return, and
|
/* Free *before* CpuHaltRequest() because it does not return, and
|
||||||
ActivateFSB() copied its argument when necessary.
|
ActivateFSB() copied its argument when necessary.
|
||||||
*/
|
*/
|
||||||
XtFree(fsb_title);
|
XtFree( fsb_title );
|
||||||
XtFree(fsb_file);
|
XtFree( fsb_file );
|
||||||
|
|
||||||
(void)CpuHaltRequest();
|
( void )CpuHaltRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
ChfCondition X_FUNC_E_NO_HALT, CHF_ERROR ChfEnd;
|
||||||
ChfCondition X_FUNC_E_NO_HALT, CHF_ERROR ChfEnd;
|
ChfSignal();
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is the emulator's extended function for 'kget': this function
|
/* This is the emulator's extended function for 'kget': this function
|
||||||
transfers a file from disk into the calculator's memory.
|
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 */
|
/* Setup File Selection Box if transfers are *not* in batch mode */
|
||||||
if(! args.batchXfer)
|
if ( !args.batchXfer )
|
||||||
SetupXfer(X_FUNC_M_KGET, "Kget", KgetContinuation);
|
SetupXfer( X_FUNC_M_KGET, "Kget", KgetContinuation );
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Ok to proceed; read:
|
||||||
/* Ok to proceed; read:
|
- file name from @D1
|
||||||
- file name from @D1
|
- target start address from A[A]
|
||||||
- target start address from A[A]
|
- target end address from C[A]
|
||||||
- target end address from C[A]
|
- binary header with BinaryHeader()
|
||||||
- binary header with BinaryHeader()
|
*/
|
||||||
*/
|
char* file_name = NameFromD1();
|
||||||
char *file_name = NameFromD1();
|
int start_addr = R2int( cpu_status.A );
|
||||||
int start_addr = R2int(cpu_status.A);
|
int end_addr = R2int( cpu_status.C );
|
||||||
int end_addr = R2int(cpu_status.C);
|
const char* bin_hdr = BinaryHeader();
|
||||||
const char *bin_hdr = BinaryHeader();
|
|
||||||
|
|
||||||
debug1(DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name);
|
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);
|
debug3( DEBUG_C_X_FUNC, X_FUNC_I_KGET, start_addr, end_addr, bin_hdr );
|
||||||
|
|
||||||
if(bin_hdr == (const char *)NULL
|
if ( bin_hdr == ( const char* )NULL || ReadObjectFromFile( file_name, bin_hdr, ( Address )start_addr, ( Address )end_addr ) ) {
|
||||||
|| ReadObjectFromFile(file_name, bin_hdr, (Address)start_addr,
|
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||||
(Address)end_addr))
|
ChfSignal();
|
||||||
{
|
}
|
||||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is the emulator's extended function for 'send': this function
|
/* This is the emulator's extended function for 'send': this function
|
||||||
transfers an object from the calculator's memory into a disk file.
|
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 */
|
/* Setup File Selection Box if transfers are *not* in batch mode */
|
||||||
if(! args.batchXfer)
|
if ( !args.batchXfer )
|
||||||
SetupXfer(X_FUNC_M_SEND, "Send", SendContinuation);
|
SetupXfer( X_FUNC_M_SEND, "Send", SendContinuation );
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
/* Ok to proceed; read:
|
||||||
/* Ok to proceed; read:
|
- file name from @D1
|
||||||
- file name from @D1
|
- source start address from A[A]
|
||||||
- source start address from A[A]
|
- source end address from C[A]
|
||||||
- source end address from C[A]
|
- binary header with BinaryHeader()
|
||||||
- binary header with BinaryHeader()
|
*/
|
||||||
*/
|
char* file_name = NameFromD1();
|
||||||
char *file_name = NameFromD1();
|
int start_addr = R2int( cpu_status.A );
|
||||||
int start_addr = R2int(cpu_status.A);
|
int end_addr = R2int( cpu_status.C );
|
||||||
int end_addr = R2int(cpu_status.C);
|
const char* bin_hdr = BinaryHeader();
|
||||||
const char *bin_hdr = BinaryHeader();
|
|
||||||
|
|
||||||
debug1(DEBUG_C_X_FUNC, X_FUNC_I_FILE_NAME, file_name);
|
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);
|
debug3( DEBUG_C_X_FUNC, X_FUNC_I_SEND, start_addr, end_addr, bin_hdr );
|
||||||
|
|
||||||
if(bin_hdr == (const char *)NULL
|
if ( bin_hdr == ( const char* )NULL || WriteObjectToFile( ( Address )start_addr, ( Address )end_addr, bin_hdr, file_name ) ) {
|
||||||
|| WriteObjectToFile((Address)start_addr,
|
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
||||||
(Address)end_addr, bin_hdr, file_name))
|
ChfSignal();
|
||||||
{
|
}
|
||||||
ChfCondition X_FUNC_W_FAILED, CHF_WARNING ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
Dispatch table of emulator's extended functions, indexed by function code;
|
Dispatch table of emulator's extended functions, indexed by function code;
|
||||||
the function code is propagated to functions in the table.
|
the function code is propagated to functions in the table.
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
typedef void (*XFunc)(Nibble);
|
typedef void ( *XFunc )( Nibble );
|
||||||
|
|
||||||
static const XFunc function[] =
|
static const XFunc function[] = {
|
||||||
{
|
SetSpeed, /* Function code 0 */
|
||||||
SetSpeed, /* Function code 0 */
|
Kget, /* 1 */
|
||||||
Kget, /* 1 */
|
Send /* 2 */
|
||||||
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.
|
the calculator side are made through CPU registers.
|
||||||
|
|
||||||
.call :
|
.call :
|
||||||
ExtendedFunction(function_code);
|
ExtendedFunction(function_code);
|
||||||
.input :
|
.input :
|
||||||
Nibble function_code, function code
|
Nibble function_code, function code
|
||||||
.output :
|
.output :
|
||||||
void
|
void
|
||||||
.status_codes :
|
.status_codes :
|
||||||
X_FUNC_I_CALLED
|
X_FUNC_I_CALLED
|
||||||
X_FUNC_I_CODE
|
X_FUNC_I_CODE
|
||||||
X_FUNC_W_BAD_CODE
|
X_FUNC_W_BAD_CODE
|
||||||
* Any other condition code generated by action functions
|
* Any other condition code generated by action functions
|
||||||
.notes :
|
.notes :
|
||||||
3.13, 3-Nov-2000, creation
|
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_TRACE, X_FUNC_I_CALLED, "ExtendedFunction" );
|
||||||
debug1(DEBUG_C_X_FUNC, X_FUNC_I_CODE, function_code);
|
debug1( DEBUG_C_X_FUNC, X_FUNC_I_CODE, function_code );
|
||||||
|
|
||||||
/* Some sanity checks, first */
|
/* Some sanity checks, first */
|
||||||
if(function_code < 0
|
if ( function_code < 0 || function_code >= N_X_FUNC || function[ ( int )function_code ] == ( XFunc )NULL ) {
|
||||||
|| function_code >= N_X_FUNC
|
ChfCondition X_FUNC_W_BAD_CODE, CHF_WARNING, function_code ChfEnd;
|
||||||
|| function[(int)function_code] == (XFunc)NULL)
|
ChfSignal();
|
||||||
{
|
|
||||||
ChfCondition X_FUNC_W_BAD_CODE, CHF_WARNING, function_code ChfEnd;
|
|
||||||
ChfSignal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dispatch */
|
/* Dispatch */
|
||||||
else
|
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()) */
|
/* Extended function codes (argument of XFunction()) */
|
||||||
#define X_FUNC_SET_SPEED (Nibble)0
|
#define X_FUNC_SET_SPEED ( Nibble )0
|
||||||
#define X_FUNC_KGET (Nibble)1
|
#define X_FUNC_KGET ( Nibble )1
|
||||||
#define X_FUNC_SEND (Nibble)2
|
#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_CALLED 101 /* Function %s called */
|
||||||
#define X_FUNC_I_CODE 102 /* Function code %d */
|
#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_SET_SPEED 103 /* Speed set to %dMhz (%d mult.) */
|
||||||
#define X_FUNC_I_MAX_SPEED 104 /* Emulator at max speed */
|
#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_FILE_NAME 105 /* Transferring file name %s */
|
||||||
#define X_FUNC_I_KGET 106 /* Kget start:%x end:%x hdr:%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_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_BAD_CODE 201 /* Bad function code %d ignored */
|
||||||
#define X_FUNC_W_ABORTED 202 /* Aborted by user */
|
#define X_FUNC_W_ABORTED 202 /* Aborted by user */
|
||||||
#define X_FUNC_W_FAILED 203 /* Operation failed */
|
#define X_FUNC_W_FAILED 203 /* Operation failed */
|
||||||
#define X_FUNC_E_NO_HALT 301 /* Cpu halt not allowed */
|
#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_SPEED 302 /* No speed control available */
|
||||||
#define X_FUNC_E_NO_BIN_HDR 303 /* Can't determine hdr for hw %s */
|
#define X_FUNC_E_NO_BIN_HDR 303 /* Can't determine hdr for hw %s */
|
||||||
#define X_FUNC_F_xxx 401
|
#define X_FUNC_F_xxx 401
|
||||||
#define X_FUNC_M_KGET 501 /* FSB title for Kget function */
|
#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_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