Author Archives: hottobar

BIOS POST procedure reverse engineering

The first thing to do in order to create a faithfull emulator of a PS/1 model 2011, able to function with the original ROM, is to do a reverse engineering of the BIOS (actually, there are other methods, but I find this one more instructive).

So here you can download a IDA Pro file with the POST procedure analyzed and commented.

Please note that this is my very first reverse engineering work and my assembly language knowledge is weak at best.

PS1_2011_ROM_IDA.zip

CMOS memory

In order to read the content of the CMOS memory of my IBM PS/1 model 2011, I wrote the following C program.
It compiles with Turbo C and it needs TASM as well.

The content of the CMOS memory of my PS/1 can be found here.

You can download a precompiled version of the program here.

Pastebin of the following program

#include <stdio.h>
#define CMOS_SIZE 64

/* 
This function reads a value from the CMOS, preserving the passed NMI bit value.
To read the CMOS this function disables NMIs. It's responsibility of the caller to inform this function 
about the current state of the NMI bit.
So to read CMOS byte 0Fh with NMI restored to enabled call read_cmos(0x0F). Call read_cmos(0x8F) otherwise.

The asm procedure was taken from the BIOS of a IBM PS/1 model 2011.
*/
unsigned char read_cmos(unsigned char _addr)
{
	unsigned char value;
	asm {
	mov	al, _addr
	pushf			/* save the CPU flags */	
	rol     al, 1		/* rotate 8-bit AL left once (AL[0] = AL[7]) */
	stc			/* CF = 1 */
	rcr     al, 1		/* save the original value of _addr[7] (the NMI bit) in CF.
				rotate 9-bits (CF, AL) right once. now AL[7]=1 (NMI disabled) and CF=AL[0] */
	cli			/* IF = 0 (disable interrupts) */
	out     70h, al		/* inform the CMOS about the memory register we want to read */
	jmp     short $+2	/* delay */
	in      al, 71h		/* read the CMOS register value and put it in AL */
	push    ax		/* save AX */
	mov     al, 1Eh		/* AL = 11110b (0Fh shifted left by 1) */
	rcr     al, 1		/* reset the NMI bit to its original value. rotate 9-bits (CF, AL) right once */
	out     70h, al		/* CMOS reg = AL (it can be 8Fh or 0Fh) */
	jmp     short $+2	/* delay */
	in      al, 71h		/* bogus CMOS read to keep the chip happy */
	pop     ax		/* restore AX */
	popf			/* restore CPU flags */
	mov	value, al	/* return the read CMOS value for index _addr */
	}
	/* 
	The "mov value, al" is redundant, because to translate "return value;" the compiler will add 
	"mov al, [bp+var_1]" at the end anyway (AL is the register where the function return value should be).
	But I will leave the instruction there, with the associated "return value;", just for clarity. 
	*/
	return value;
}

int main()
{
	unsigned char p, cmos[CMOS_SIZE];
	FILE *outf;
	
	/* read the CMOS in its entirety */
	for(p=0; p<CMOS_SIZE; p++) {
		cmos[p] = read_cmos(p);
	}
	
	/* write the CMOS data to screen and file */
	outf = fopen("cmos.txt","w");
	if(outf == NULL) {
		printf("error opening file\n");
		return 1;
	}
	for(p=0; p<CMOS_SIZE; p++) {
		printf("[%2X=%2X] ", p, cmos[p]);
		fprintf(outf, "%2X = %2X\n", p, cmos[p]);
	}
	fclose(outf);
	
	return 0;
}

The IBM PS/1 model 2011

 

More in-depth and up-to-date info at this page: IBM PS/1 model 2011

 

IBMPS1

Release date 1990
Operating system PC DOS 4.01 (in ROM)
CPU Intel 80286 @ 10 MHz
RAM 512 KB ~ 1 MB
Hard Drive (optional) 30MB

At boot you are presented with a mouse driven graphical interface, loaded directly from ROM:

1644201-boot_screen_1k
(U.S. version shown)

A ROM drive is mounted as D:\ containing the IBM DOS 4.01 files.

The DOS, BIOS, and GUI are stored in 27C010 1M EPROM chips.
The ROM subsystem consists of either two 128K-by-8-bit modules (U.S. models) or four 128K-by-8-bit modules (other countries) arranged in 16 bit words. 512KB of ROM are addressed from F80000 to FFFFFF. Addresses FE0000 to FFFFFF are also addressed as 0E0000 to 0FFFFF.

ROMs

Here you can download the 4 EPROMs images of an italian PS/1  model 2011  (the ones in the image above):

u18-x1-1057630.bin
u23-x2-1057757.bin
u28-x3-1057759.bin
u36-x4-1057628.bin

In order to read the content, you need to merge U36 with U18 and U23 with U28, taking one byte from the first bin file, one from the second, and so on and so forth, actually interleaving the data.
Or you can download the already merged versions:

u23-u28.bin
u36-u18.bin

u23-u28.bin contains the system BIOS, which I already extracted for your convenience:

SYS_ROM.BIN

Like all ATs, the BIOS is mapped in memory at F000:0000 and is 64KB in size. The BIOS includes the BASIC interpreter.

Every detail about the hardware can be found inside the IBM’s book Technical Reference for PS/1 Computer (P/N 57F1970).

ps1_tech_ref

This book is rarer than a pink unicorn, but I’ve managed to get hold of a copy.

Complete book (532 pages), 1st edition 1990
searchable and indexed (there’s some mistake in the OCRred text, notably some 0 -zero- mistaken for O or C, 3 for B, etc, so consider this when searching for text)

Technical Reference for PS1 Computer – PN 57F1970.pdf

Single sections
every file is searchable

Preface.pdf
TOC.pdf
Section 1. System Description.pdf
Section 2. System Board.pdf
Section 3. System Board IO Controllers.pdf
Section 4. Power Supply.pdf
Section 5. Keyboard.pdf
Section 6. Mouse.pdf
Section 7. Displays.pdf
Section 8. Drives.pdf
Section 9. Modem RS-232C Interface Cards.pdf
Section 10. 80286 Instruction Set.pdf
Section 11. Characters and Keystrokes.pdf
Section 12. Compatibility.pdf
Appendix. Options.pdf