Tag Archives: Windows

SINFO.EXE or playing with bios interrupts on my PC XT clone

I am stuck with a problem in the game I work on for several days now. When I’m stuck I usually do something else for a couple of hours. For example playing with bios interrupts on my PC XT clone (which by the way is completely restored, but more on this in the upcoming posts).

Pravetz 16 (IBM PC XT clone)

Pravetz 16 (IBM PC XT clone) and yes that’s Windows 3.0.

NOTE: Writing code on monochrome monitor is something that every software developer should do at least ones in his career 🙂

What’s interrupt? (From Wikipedia articles on interrupts)

In system programming, an interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. An interrupt alerts the processor to a high-priority condition requiring the interruption of the current code the processor is executing. The processor responds by suspending its current activities, saving its state, and executing a function called an interrupt handler (or an interrupt service routine, ISR) to deal with the event. This interruption is temporary, and, after the interrupt handler finishes, the processor resumes normal activities.[1] There are two types of interrupts: hardware interrupts and software interrupts.

The code below calls software interrupts 11h (Equipment Installed) and 12h (Memory Available) using inline assembly. To compile the source you will need Turbo C and TASM. They both run perfectly fine under DOSBox.

The executable is available for download here.

#include 
 
int main(void)
{
  int systemInfo;
  int floppyCount;
  int mem, memSize, memSizePost;
  int videoMode;
  int serialPorts;
  int paralelPorts;
 
  /* Call INT 11h ( Equipment Installed ) */
  asm int 11h;
  asm mov systemInfo, ax;
 
  /* Call INT 12h ( Memory Available ) */
  asm int 12h;
  asm mov memSizePost, ax;
 
  printf("********** SYSTEM INFO ***********\n");
  printf("Floppy drive(s): %s ", (systemInfo & 0x0001) ? "yes" : "no");
 
  if((systemInfo & 0x0001))
  {
    switch((systemInfo & 0x00C0))
    {
      case 0:
      {
		floppyCount = 1;
		break;
      }
      case 64:
      {
		floppyCount = 2;
		break;
      }
      case 128:
      {
		floppyCount = 3;
		break;
      }
      case 192:
      {
		floppyCount = 4;
		break;
      }
    }
 
    printf("(%d)\n", floppyCount);
  }
  else
  {
    printf("\n");
  }
 
 
  printf("Math co-processor: %s\n", (systemInfo & 0x0002) ? "yes" : "no");
 
  mem = (systemInfo & 0x000C);
 
  switch(mem)
  {
    case 0:
    {
      memSize = 16;
      break;
    }    
    case 4:
    {
      memSize = 32;
      break;
    }
    case 8:
    {
      memSize = 48;
      break;
    }
    case 12:
    {
      memSize = 256;
      break;
    }
  }
  printf("On-board memory: %d K%s\n", memSize, (memSize >= 256) ? "+" : " ");
  printf("Memory reported by BIOS POST: %dK\n", memSizePost);
 
  videoMode = (systemInfo & 0x0030);
  switch(videoMode)
  {
    case 0:
    {
      printf("Video mode: EGA, VGA or PGA\n");
      break;
    }
    case 16:
    {
      printf("Video mode: CGA, 40 x 25\n");
      break;
    }
    case 32:
    {
      printf("Video mode: CGA, 80 x 25\n");
      break;
    }
    case 48:
    {
      printf("Video mode: monochrome, 80 x 25\n");
      break;
    }
  }
 
  printf("DMA support: %s\n", (systemInfo & 0x0100) == 0 ? "yes" : "no");
  printf("Game adapter: %s\n", (systemInfo & 0x1000) == 0 ? "no" : "yes");
 
  switch((systemInfo & 0x0E00))
  {
    case 0:
    {
      serialPorts = 0;
      break;
    }
    case 512:
    {
      serialPorts = 1;
      break;
    }
    case 1024:
    {
      serialPorts = 2;
      break;
    }
    case 1536:
    {
      serialPorts = 3;
      break;
    }
    case 2048:
    {
      serialPorts = 4;
      break;
    }
  }
  printf("Serial ports: %d\n", serialPorts);
 
  switch((systemInfo & 0xC000))
  {
    case 0:
    {
      paralelPorts = 0;
      break;
    }
    case 16384:
    {
      paralelPorts = 1;
      break;
    }
    case 32768:
    {
      paralelPorts = 2;
      break;
    }
    case 49152:
    {
      paralelPorts = 3;
      break;
    }
  }
  printf("Paralel ports: %d\n", paralelPorts);
 
  return 0;
}

Get Android Studio debug certificate fingerprints on Windows

Here is a small batch file that will retrieve Android Studio debug certificate fingerprints. Make sure that keytool.exe is in your %PATH%

@echo off
keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
pause

Copy / paste the a bough commands in an empty file and save it with a .bat extension.

Android Studio debug certificate fingerprints

Android Studio debug certificate fingerprints

Hard Reset: Nokia XpressMusic 5800

Here is how to hard reset (back to factory default settings) the Nokia XpressMusic 5800.

I suggest backing up your phone’s contents using Nokia PC Suite before proceeding, because a hard reset will erase everything on your phone. If you have a memory card, I also suggest backing up its contents and then formatting it, because some apps you downloaded through the Ovi Store may be installed on the memory card. After the hard reset, when you reinsert the memory card, those apps may reinstall automatically.

To hard reset your phone using the on-screen keypad, enter the following code:

*#7370#

When prompted for the security code, enter:

12345

Your phone will restart and, after it finishes booting, it should be as good as new.

CLastError

Small class for resolving and presenting in user readable form the codes from ::GetLastError() Win32 API function. The class has 2 static methods:

1
2
3
4
5
6
7
8
9
10
void CLastError::Get( const DWORD& dwErrorCode, CString& strErrMessage )
{
	LPTSTR lpErrorText = NULL;
 
	::FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 
		0, dwErrorCode, 0, lpErrorText, MAX_PATH, 0 );
 
	strErrMessage = lpErrorText;
	::LocalFree( lpErrorText );
}

The ‘Get’ method supplied an error code will resolve the code to user readable error message and store it in the supplied ‘strErrMessage’ string!

1
2
3
4
5
6
7
8
9
10
11
12
void CLastError::Show( const DWORD& dwErrorCode, const CString& strAppName )
{
	CString strErrMessage;
	Get( dwErrorCode, strErrMessage );
 
	CString strDisplayError;
	strDisplayError.Format( 
		_T("%s encountered an error and needs to close!\n\nError was: %s"),
		strAppName, strErrMessage );
 
	AfxMessageBox( strDisplayError, MB_ICONERROR | MB_OK );
}

The ‘Show’ method supplied an error code will resolve the code to user readable error message and the message will be displayed to the user trough AfxMessageBox() function.

Class declaration:

class CLastError
{
public:
 
	CLastError( );
	virtual ~CLastError( );
 
public:
 
	static void Get( const DWORD& dwErrorCode, CString& strErrMessage );
	static void Show( const DWORD& dwErrorCode, const CString& strAppName );
};

Class implementation:

CLastError::CLastError( )
{
}
 
CLastError::~CLastError( )
{
}
 
void CLastError::Get( const DWORD& dwErrorCode, CString& strErrMessage )
{
	LPTSTR lpErrorText = NULL;
 
	::FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 
		0, dwErrorCode, 0, lpErrorText, MAX_PATH, 0 );
 
	strErrMessage = lpErrorText;
	::LocalFree( lpErrorText );
}
 
void CLastError::Show( const DWORD& dwErrorCode, const CString& strAppName )
{
	CString strErrMessage;
	Get( dwErrorCode, strErrMessage );
 
	CString strDisplayError;
	strDisplayError.Format( 
		_T("%s encountered an error and needs to close!\n\nError was: %s"),
		strAppName, strErrMessage );
 
	AfxMessageBox( strDisplayError, MB_ICONERROR | MB_OK );
}

vHash

vHash is small Windows utility for generating hashes using various cryptography providers and algorithms that they support such as MD-5, SHA-1, etc. It’s written on C using Win32 API making it light and dependency free.

Currently the utility does not support keyed hash algorithms such as HMAC or MAC. Also the program is Unicode.

vHash

Downloads and more information are available on the vHash project page.