static void GoToRealMode( void *rm_func ) { unsigned i; PMData->rm_func = RM_OFF( rm_func ); if( IntrState == IS_DPMI ) { for( i = 0; i < NUM_PM_SAVE_VECTS; ++i ) { DPMISetPMInterruptVector( PMVectSaveList[i], SavePMVects[i] ); } for( i = 0; i < NUM_PM_SAVE_EXCEPTS; ++i ) { DPMISetPMExceptionVector( PMExceptSaveList[i], SavePMExcepts[i] ); } DoRawSwitchToRM( RMData.segm.rm, offsetof( rm_data, stack ) + STACK_SIZE, RM_OFF( RawSwitchHandler ) ); for( i = 0; i < NUM_PM_SAVE_EXCEPTS; ++i ) { SavePMExcepts[i] = DPMIGetPMExceptionVector(PMExceptSaveList[i]); DPMISetPMExceptionVector( PMExceptSaveList[i], OrigPMExcepts[i] ); } for( i = 0; i < NUM_PM_SAVE_VECTS; ++i ) { SavePMVects[i] = DPMIGetPMInterruptVector( PMVectSaveList[i] ); DPMISetPMInterruptVector( PMVectSaveList[i], OrigPMVects[i] ); } } else { DoIntSwitchToRM(); } }
static char *SetTrapHandler( void ) { char dummy; long result; descriptor desc; version_info ver; PMData->vecttable1[DOS4G_COMM_VECTOR].s.segment = RMData.segm.rm; PMData->vecttable1[DOS4G_COMM_VECTOR].s.offset = RM_OFF( Interrupt15 ); PMData->vecttable2[DOS4G_COMM_VECTOR].s.segment = RMData.segm.rm; PMData->vecttable2[DOS4G_COMM_VECTOR].s.offset = RM_OFF( Interrupt15 ); if( IntrState == IS_NONE ) { DPMIGetVersion( &ver ); if( (ver.major_version >= 1 || ver.minor_version > 90) || DPMICheck == 2 ) { RawPMtoRMSwitchAddr = DPMIRawPMtoRMAddr(); PMData->switchaddr.a= DPMIRawRMtoPMAddr(); } if( RawPMtoRMSwitchAddr == 0 || PMData->switchaddr.a == 0 || DPMICheck == 1 ) { IntrState = IS_RATIONAL; } else { PMData->saveaddr.a = DPMISavePMStateAddr(); PMData->savesize = DPMISaveStateSize(); if( PMData->savesize == 0 ) { PMData->saveseg.dpmi_adr = 0; } else { PMData->saveseg.dpmi_adr = DPMIAllocateDOSMemoryBlock( _NBPARAS(PMData->savesize*2) ); if( PMData->saveseg.segm.pm == 0 ) { return( TC_ERR_OUT_OF_DOS_MEMORY ); } } PMData->othersaved = false; result = DPMIAllocateLDTDescriptors( 1 ); if( result < 0 ) { return( TC_ERR_CANT_LOAD_TRAP ); } DPMIGetDescriptor( FP_SEG( PMData ), &desc ); PMData->pmode_cs = (unsigned_16)result; desc.xtype.use32 = 0; desc.type.execute = 1; DPMISetDescriptor( PMData->pmode_cs, &desc ); PMData->pmode_eip = RM_OFF( BackFromRealMode ); PMData->pmode_ds = FP_SEG( &PMData ); PMData->pmode_es = PMData->pmode_ds; PMData->pmode_ss = FP_SEG( &dummy ); IntrState = IS_DPMI; } } if( IntrState == IS_RATIONAL ) { MySetRMVector( TRAP_VECTOR, RMData.segm.rm, RM_OFF( RMTrapHandler ) ); } return( NULL ); }
void GrabHandlers( void ) { PMData->oldint10.a = MyGetRMVector( 0x10 ); OldInt1b.a = MyGetRMVector( CTRL_BREAK_VECTOR ); OldInt23.a = MyGetRMVector( 0x23 ); OldInt24.a = MyGetRMVector( 0x24 ); OldInt28.a = MyGetRMVector( 0x28 ); MySetRMVector( 0x10, RMData.s.rm, RM_OFF( Interrupt10 ) ); MySetRMVector( CTRL_BREAK_VECTOR, RMData.s.rm, RM_OFF( Interrupt1b_23 ) ); MySetRMVector( 0x23, RMData.s.rm, RM_OFF( Interrupt1b_23 ) ); MySetRMVector( 0x24, RMData.s.rm, RM_OFF( Interrupt24 ) ); MySetRMVector( 0x28, Orig28.s.segment, Orig28.s.offset ); }
/** IPX_Disconnect Documentation states: "Only use in point-to-point networks". Not completely sure what that means; DOSBox doesn't even implement this call, and as for real networks, I can only hope we'll be fine :) */ void IPX_Disconnect(const IPX_Address *address) { RM_Info rm{}; rm.es = RM_SEG(address); rm.esi = RM_OFF(address); rm.ebx = 0x000b; RM_Interrupt(0x7a, &rm); }
void IPX_Cancel(ECB *ecb) { RM_Info rm{}; rm.es = RM_SEG(ecb); rm.esi = RM_OFF(ecb); rm.ebx = 0x0006; RM_Interrupt(0x7a, &rm); if (rm.eax & 0xff) WriteToLog("IPX_Cancel failed, error code: %d", rm.eax & 0xff); }