📄 os2v1acc.c
字号:
SaveStdIn = NIL_DOS_HANDLE;
SaveStdOut = NIL_DOS_HANDLE;
if( Pid != 0 ) {
Buff.cmd = PT_CMD_TERMINATE;
DosPTrace( &Buff );
}
NumModHandles = 0;
CurrModHandle = 1;
Pid = 0;
ret->err = 0;
return( sizeof( *ret ) );
}
unsigned ReqSet_break()
{
byte ch;
set_break_req *acc;
set_break_ret *ret;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ReadBuffer( &ch, acc->break_addr.segment, acc->break_addr.offset, sizeof(byte) );
ret->old = ch;
ch = 0xCC;
WriteBuffer( &ch, acc->break_addr.segment, acc->break_addr.offset, sizeof(byte) );
return( sizeof( *ret ) );
}
unsigned ReqClear_break()
{
clear_break_req *bp;
byte ch;
bp = GetInPtr( 0 );
ch = bp->old;
WriteBuffer( &ch, bp->break_addr.segment, bp->break_addr.offset, sizeof(byte) );
return( 0 );
}
unsigned ReqSet_watch()
{
set_watch_req *wp;
set_watch_ret *wr;
dword buff;
wp = GetInPtr( 0 );
wr = GetOutPtr( 0 );
if( WatchCount < MAX_WP ) { // nyi - artificial limit (32 should be lots)
WatchPoints[ WatchCount ].addr.segment = wp->watch_addr.segment;
WatchPoints[ WatchCount ].addr.offset = wp->watch_addr.offset;
ReadBuffer( (char far *)&buff, wp->watch_addr.segment,
wp->watch_addr.offset, sizeof(dword) );
WatchPoints[ WatchCount ].value = buff;
++WatchCount;
} else {
wr->err = 84; /* out of structures */
}
wr->multiplier = 50000;
return( sizeof( *wr ) );
}
unsigned ReqClear_watch()
{
clear_watch_req *wp;
watch *dst;
watch *src;
int i;
wp = GetInPtr( 0 );
dst = src = WatchPoints;
for( i = 0; i < WatchCount; ++i ) {
if( src->addr.segment != wp->watch_addr.segment
|| src->addr.offset != wp->watch_addr.offset ) {
*dst = *src;
++dst;
}
++src;
}
--WatchCount;
return( 0 );
}
static volatile bool BrkPending;
static void pascal far __loadds BrkHandler( USHORT sig_arg, USHORT sig_num )
{
PFNSIGHANDLER prev_hdl;
USHORT prev_act;
sig_arg = sig_arg;
BrkPending = TRUE;
DosSetSigHandler( BrkHandler, &prev_hdl, &prev_act, 4, sig_num );
}
static unsigned MapReturn( unsigned changes )
{
if( BrkPending ) {
ReadRegs( &Buff );
return( changes | COND_USER );
}
switch( Buff.cmd ) {
case PT_RET_SUCCESS:
return( changes );
case PT_RET_SIGNAL:
return( changes | COND_USER );
case PT_RET_STEP:
return( changes | COND_TRACE );
case PT_RET_BREAK:
return( changes | COND_BREAK );
case PT_RET_PARITY:
ExceptNum = 2;
return( changes | COND_EXCEPTION );
case PT_RET_FAULT:
ExceptNum = 13;
return( changes | COND_EXCEPTION );
case PT_RET_WATCH:
return( changes | COND_WATCH );
case PT_RET_LIB_LOADED:
RecordModHandle( Buff.value );
return( changes | COND_LIBRARIES );
case PT_RET_TRD_TERMINATE:
return( changes );
// Combined PT_RET_FUNERAL & PT_RET_ERROR with default
// case PT_RET_FUNERAL:
// case PT_RET_ERROR:
default:
CanExecTask = FALSE;
AtEnd = TRUE;
return( changes | COND_TERMINATE );
}
}
static unsigned ProgRun( bool step )
{
watch *wp;
int i;
PFNSIGHANDLER prev_brk_hdl;
USHORT prev_brk_act;
PFNSIGHANDLER prev_intr_hdl;
USHORT prev_intr_act;
prog_go_ret *ret;
ExceptNum = -1;
ret = GetOutPtr( 0 );
if( NumModHandles > CurrModHandle ) {
ret->conditions = COND_LIBRARIES;
return( sizeof( *ret ) );
}
BrkPending = FALSE;
DosSetSigHandler( BrkHandler, &prev_intr_hdl, &prev_intr_act, 2, SIG_CTRLC );
DosSetSigHandler( BrkHandler, &prev_brk_hdl, &prev_brk_act, 2, SIG_CTRLBREAK );
if( AtEnd ) {
Buff.cmd = PT_RET_FUNERAL;
} else if( step ) {
Buff.cmd = PT_CMD_SINGLE_STEP;
DosPTrace( &Buff );
} else if( WatchCount != 0 ) {
for( ;; ) {
Buff.cmd = PT_CMD_SINGLE_STEP;
DosPTrace( &Buff );
if( Buff.cmd != PT_RET_STEP ) break;
for( wp = WatchPoints,i = WatchCount; i > 0; ++wp, --i ) {
Buff.cmd = PT_CMD_READ_MEM_D;
Buff.segv = wp->addr.segment;
Buff.offv = wp->addr.offset;
DosPTrace( &Buff );
if( Buff.value != wp->value ) {
Buff.cmd = PT_RET_WATCH;
goto leave;
}
}
}
} else {
Buff.cmd = PT_CMD_GO;
Buff.value = 0;
if( DosPTrace( &Buff ) == ERROR_INTERRUPT ) {
BrkPending = TRUE;
}
if( Buff.cmd == PT_RET_SUCCESS ) { /* a successful GO means pgm done! */
Buff.cmd = PT_RET_FUNERAL;
}
}
leave:
DosSetSigHandler( prev_brk_hdl, &prev_brk_hdl, &prev_brk_act,
prev_brk_act, SIG_CTRLBREAK );
DosSetSigHandler( prev_brk_hdl, &prev_intr_hdl, &prev_intr_act,
prev_brk_act, SIG_CTRLC );
ret->conditions = COND_CONFIG | COND_THREAD;
if( NumModHandles > CurrModHandle ) {
ret->conditions |= COND_LIBRARIES;
}
ret->conditions = MapReturn( ret->conditions );
ret->program_counter.offset = Buff.u.r.IP;
ret->program_counter.segment = Buff.u.r.CS;
ret->stack_pointer.offset = Buff.u.r.SP;
ret->stack_pointer.segment = Buff.u.r.SS;
return( sizeof( *ret ) );
}
unsigned ReqProg_go()
{
return( ProgRun( FALSE ) );
}
unsigned ReqProg_step()
{
return( ProgRun( TRUE ) );
}
unsigned ReqFile_write_console()
{
USHORT len;
USHORT written_len;
unsigned save_ax;
unsigned save_dx;
unsigned save_bx;
char *ptr;
unsigned curr;
file_write_console_ret *ret;
ptr = GetInPtr( sizeof( file_write_console_req ) );
len = GetTotalSize() - sizeof( file_write_console_req );
ret = GetOutPtr( 0 );
if( CanExecTask ) {
ret->len = len;
ret->err = 0;
/* print/program request */
save_ax = Buff.u.r.AX;
save_dx = Buff.u.r.DX;
save_bx = Buff.u.r.BX;
ret->err = 0;
while( len != 0 ) {
curr = len;
if( len > sizeof( UtilBuff ) ) len = sizeof( UtilBuff );
WriteBuffer( ptr, FP_SEG( UtilBuff ), FP_OFF( UtilBuff ), curr );
Buff.u.r.AX = FP_OFF( UtilBuff );
Buff.u.r.DX = FP_SEG( UtilBuff );
Buff.u.r.BX = curr;
TaskExecute( DoWritePgmScrn );
ptr += curr;
len -= curr;
}
Buff.u.r.AX = save_ax;
Buff.u.r.DX = save_dx;
Buff.u.r.BX = save_bx;
} else {
ret->err = DosWrite( 2, ptr, len, &written_len );
ret->len = written_len;
}
return( sizeof( *ret ) );
}
static int ValidThread( TID thread )
{
struct thd_state state;
TID save;
save = Buff.tid;
Buff.tid = thread;
Buff.cmd = PT_CMD_THREAD_STAT;
Buff.segv = FP_SEG( &state );
Buff.offv = FP_OFF( &state );
DosPTrace( &Buff );
Buff.tid = save;
return( Buff.cmd == PT_RET_SUCCESS );
}
unsigned ReqThread_get_next()
{
thread_get_next_req *acc;
thread_get_next_ret *ret;
TID thread;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
if( Pid != 0 ) {
thread = acc->thread;
while( ++thread <= 256 ) {
if( ValidThread( thread ) ) {
ret->thread = thread;
//NYI:Assume all threads can be run
ret->state = THREAD_THAWED;
return( sizeof( *ret ) );
}
}
}
if( ret->thread == 0 ) {
ret->thread = 1;
} else {
ret->thread = 0;
}
return( sizeof( *ret ) );
}
unsigned ReqThread_set()
{
thread_set_req *acc;
thread_set_ret *ret;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->err = 0;
ret->old_thread = Buff.tid;
if( acc->thread != 0 && ValidThread( acc->thread ) ) {
Buff.tid = acc->thread;
Buff.cmd = PT_CMD_READ_REGS;
DosPTrace( &Buff );
}
return( sizeof( *ret ) );
}
static unsigned DoThread( trace_codes code )
{
TID save;
thread_thaw_req *acc;
thread_thaw_ret *ret;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
if( ValidThread( acc->thread ) ) {
save = Buff.tid;
Buff.tid = acc->thread;
Buff.cmd = code;
DosPTrace( &Buff );
Buff.tid = save;
ret->err = 0;
} else {
ret->err = 1; // failed
}
return( sizeof( *ret ) );
}
unsigned ReqThread_freeze()
{
return( DoThread( PT_CMD_FREEZE ) );
}
unsigned ReqThread_thaw()
{
return( DoThread( PT_CMD_RESUME ) );
}
unsigned ReqGet_lib_name()
{
get_lib_name_req *acc;
get_lib_name_ret *ret;
char *name;
acc = GetInPtr(0);
ret = GetOutPtr(0);
if( acc->handle != 0 ) {
CurrModHandle = acc->handle + 1;
}
if( CurrModHandle >= NumModHandles ) {
ret->handle = 0;
return( sizeof( *ret ) );
}
name = GetOutPtr( sizeof(*ret) );
Buff.value = ModHandles[ CurrModHandle ];
Buff.segv = FP_SEG( name );
Buff.offv = FP_OFF( name );
Buff.cmd = PT_CMD_GET_LIB_NAME;
DosPTrace( &Buff );
ret->handle = CurrModHandle;
return( sizeof( *ret ) + strlen( name ) + 1 );
}
unsigned ReqGet_message_text()
{
static const char * const ExceptionMsgs[] = {
TRP_EXC_divide_overflow,
"",
TRP_EXC_non_maskable_interrupt,
"",
TRP_EXC_integer_overflow,
TRP_EXC_bounds_check,
TRP_EXC_invalid_opcode,
TRP_EXC_coprocessor_not_available,
TRP_EXC_double_fault,
TRP_EXC_coprocessor_segment_overrun,
TRP_EXC_invalid_TSS,
TRP_EXC_segment_not_present,
TRP_EXC_stack_exception,
TRP_EXC_general_protection_fault,
TRP_EXC_page_fault,
"",
TRP_EXC_coprocessor_error,
TRP_EXC_data_type_misalignment,
};
get_message_text_ret *ret;
char *err_txt;
ret = GetOutPtr( 0 );
err_txt = GetOutPtr( sizeof(*ret) );
if( ExceptNum == -1 ) {
err_txt[0] = '\0';
} else if( ExceptNum > ( (sizeof(ExceptionMsgs) / sizeof(char *) - 1) ) ) {
strcpy( err_txt, TRP_EXC_unknown );
} else {
strcpy( err_txt, ExceptionMsgs[ ExceptNum ] );
}
ExceptNum = -1;
ret->flags = MSG_NEWLINE | MSG_ERROR;
return( sizeof( *ret ) + strlen( err_txt ) + 1 );
}
unsigned ReqGet_next_alias()
{
get_next_alias_ret *ret;
ret = GetOutPtr( 0 );
ret->seg = 0;
ret->alias = 0;
return( sizeof( *ret ) );
}
trap_version TRAPENTRY TrapInit( char *parm, char *err, unsigned_8 remote )
{
trap_version ver;
USHORT os2ver;
SEL li,gi;
__LINFOSEG far *linfo;
parm = parm;
Remote = remote;
err[0] = '\0';
ver.major = TRAP_MAJOR_VERSION;
ver.minor = TRAP_MINOR_VERSION;
ver.remote = FALSE;
SaveStdIn = NIL_DOS_HANDLE;
SaveStdOut = NIL_DOS_HANDLE;
Screen = DEBUG_SCREEN;
DosGetVersion( &os2ver );
if( os2ver < 0x114 ) {
strcpy( err, TRP_OS2_not_1p2 );
return( ver );
}
if( DosGetInfoSeg( &gi, &li ) != 0 ) {
strcpy( err, TRP_OS2_no_info );
return( ver );
}
GblInfo = MK_FP( gi, 0 );
linfo = MK_FP( li, 0 );
if( linfo->typeProcess == _PT_FULLSCREEN ) {
SessionType = SSF_TYPE_FULLSCREEN;
} else {
SessionType = SSF_TYPE_WINDOWABLEVIO;
}
ExceptNum = -1;
return( ver );
}
void TRAPENTRY TrapFini()
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -