Page 2 of 2

Re: PSone BIOS modding project

Posted: September 5th, 2013, 5:41 am
by legacy
i am planning to replace the PSone's bios with a NVram @ 3.3V
also i am planning to do the same on an old playstation1.

i'd like to replace the firmware, too, with something extremely easy and essential, just to toy with the uart.

Re: PSone BIOS modding project

Posted: September 5th, 2013, 9:06 am
by legacy
It looks very similar to 29040 eprom, very interesting =)

Re: PSone BIOS modding project

Posted: September 6th, 2013, 12:01 am
by legacy
cybdyn wrote:bios is sourced by 3.3v. )) but in some cases AR used 5v flash IC. it gets from 7.5v from parralel-io through down dc/dc converter
yes, i confirm:
1) PSOne has MASK-Rom.vcc=3.3V
2) Playstation1 has MASK-Rom.vcc=3.3V

my AR has a 29xxx flash (in DIP package) with vcc=5V through an LDO regulator 7805

the PIO should be at 3.3V, wondering if 5V tolerant.

Re: PSone BIOS modding project

Posted: April 23rd, 2016, 12:43 pm
by aarkay14
Hi All

Sorry for necro bumping old topic but did the reverse engineered BIOS did make out of this project?
Can we compile the code in the first page to hardware?

-Rama

Re: PSone BIOS modding project

Posted: June 22nd, 2018, 7:06 pm
by Dedok179
Shadow wrote: May 5th, 2012, 4:54 pm Sony PlayStation BIOS from http://www.geocities.co.jp/playtown/2004/psx/
Possibly created by Bero for NOT YAROZE.

WARNING: Copy and paste this text into a text document. It is very long.
I reccomend that you use under Windows the Programmers Notepad. Set it to 'C / C++' mode.

Code: Select all

/* 0xbfc00000 */
start()
{
	_0x1f801010 = 0x0013243f;
	*ram_size = 0x00000b88;
	jmp_part0();
}

/* 0xbfc00150 */
part0()
{
	*com_delay = 0x00031125;
	_0x1f801000 = 0x1f000000;
	_0x1f801004 = 0x1f002000;
	_0x1f801008 = 0x0013243f;
	*spu_delay = 0x200931e1;
	*dv5_delay = 0x00020843;
	_0x1f80100c = 0x00003022;
	_0x1f80101c = 0x00070777;
	clear_all_registers(); /* inline */
	_0xfffe0130 = 0x00000804;
	/* Flushing Cache begin */
		/* details deleted */
	/* Flushing Cache end */
	tmp = _0xa0000000;
	tmp = _0x00000000;
	tmp = _0x00000000;
	tmp = _0x00000000;
	tmp = _0x00000000;
	tmp = _0x00000000;
	tmp = _0x00000000;
	tmp = _0x00000000;
	_0xfffe0130 = 0x0001e988;
	C0.DCIC = 0;
	C0.BPC = 0;
	C0.BDA = 0;
	C0.TAR = 0;
	C0.BDAM = 0;
	C0.BPCM = 0;
	C0.SR = 0;
	C0.CAUSE = 0;
	for (tmp = 0xa0009000 ; tmp != 0xa000c160 ; tmp++)
		*tmp=0;
	_stk = 0x801fff00;
	_gp_ = 0xa0010ff0;
	_fp_ = _stk;
	*ram_size = 0x00000b88;
	_0x00000060=2;
	_0x00000064=0;
	_0x00000068=0xff;
	zero_stuff();
	jump_part2();
}


SysInitKMem() /* 0xbfc00420 */
{
	long count , *src , *dst;

	src = 0xbfc10000;
	dst = 0xa0000500;
	for (count = 0x8fb0 ; count != 0 ; count -= 4)
		*dst++ = *src++;
	jmp_0xa0000500();
}


/* 0xbfc00460 */
ColorBars()
{
	SendGPU(0);		/* Some kind of reset ? */
	Clear_();
	SendGPU(0x03000000);	/* Display Mask (enable display) */
	Clear_();
	SendGPU(0x06c60260);	/* Screen horizontal start/end */
	Clear_();
	SendGPU(0x07040010);	/* Screen vertical start/end */
	Clear_();
	GPU_cw(0xe1000400);	/* Draw on display area */
	Clear_();
	GPU_cw(0xe3000000);	/* Draw Area x, y */
	Clear_();
	GPU_cw(0xe407ffff);	/* Draw Area w, h */
	Clear_();
	GPU_cw(0xe5000000);	/* Draw Offset */
	Clear_();
	SendGPU(0x08000000);	/* Display mode, 256x240/NTSC/noninterlaced */
	Clear_();
	SendGPU(0x08000000);	/* Display mode, 256x240/NTSC/noninterlaced */
	Clear_();
	DrawBackground();
	SendGPU(0x08000000);	/* Display mode, 256x240/NTSC/noninterlaced */
	Clear_();
	DrawBackground();
	Rectangle(  0,   0,  32, 241, 255, 255, 255);
	Rectangle( 32,   0,  32, 241, 255, 255,   0);
	Rectangle( 64,   0,  32, 241,   0, 255, 255);
	Rectangle( 96,   0,  32, 241,   0, 255,   0);
	Rectangle(128,   0,  32, 241, 255,   0, 255);
	Rectangle(160,   0,  32, 241, 255,   0,   0);
	Rectangle(192,   0,  32, 241,   0,   0, 255);
	Rectangle(224,   0,  32, 241,   0,   0,   0);

	return 0;
}

/* 0xbfc00778 */
DrawBackground()
{
	Rectangle(  0 ,   0 , 513 , 257 ,   0 ,   0 ,   0);
	Rectangle(  0 , 256 , 513 , 257 ,   0 ,   0 ,   0);
	Rectangle(512 ,   0 , 513 , 257 ,   0 ,   0 ,   0);
	Rectangle(512 , 256 , 513 , 257 ,   0 ,   0 ,   0);
}


/* 0xbfc00810 */
Rectangle(int x , int y , int w , int h , int R , int G , int B)
{
	long local[5];

	local[0] = ((B << 16) | 0x28000000) | (G << 8) | (R);
	local[1] = (y << 16) | (x);
	local[2] = (y << 16) | (x + w);
	local[3] = ((y + h) << 16) | (x);
	local[4] = ((y + h) << 16) | (x + w);
	GPU_cwb(local , 5);
}

ParseSetupFile(char *buf,TCBEV *a,char *boot)
{
	long tmp,*z;

	z=a;
	for (tmp=0 ; tmp !=3 ; ++tmp) {
		*z++=0;
	}
	*boot="\0";
	_0x00000180=(char)0;
	GetValue(buf , &a->Tcb , "TCB");
	GetValue(buf , &a->Event , "EVENT");
	GetValue(buf , &a->Stack , "STACK");
	GetString(buf , boot , 384 , "BOOT");
}
	
__trace(char value)
{
	_1f802041 = value;
	Clear0XA001B068();
}


/* sys_a0_42 0xbfc03a18 */
int Load(char *name,struct EXEC *header)
{
	int fd;
	
	if ((fd = open(name,1)) <0) {
		return 0;
	}
	if (ReadExeHeader(fd , header)="=" 0) {
		close(fd); return 0;
	}
	read(fd , header->t_addr , header->t_size);
	close(fd);
	FlushCache();
	
	return 1;
}


/* 0xbfc03aa4 */
LoadExec(char *name , int argc , char **argv)
{
	char *src,*dst;
	char tmp[32];

	src = name;
	dst = tmp;
	while (*src && *src != ':') {
		*dst++ = *src++;
	}
	while (*dst++ = toupper(*src++)) ;
	dst = tmp;
	while (*dst && *dst != ';') {
		dst++;
	}
	if (!*dst) {
		strcat(tmp,";1");
	}
	_0xa0009144 = _0xa000b890;
	_0xa0009148 = _0xa000b894;
	ExitCriticalSection();
	if (Load(tmp , ExeHeader) == 1) {
		_0xa000b890 = argc;
		_0xa000b894 = argv;
		Exec(ExeHeader , tmp , 0);
	} else {
		printf("No EXE-file !\n");
	}
	printf("Execute the boot file %s.\n" , BootFile);
	ExitCriticalSection();
	if (Load(BootFile,ExeHeader) == 1) {
		_0xa000b890 = _0xa0009144;
		_0xa000b894 = _0xa0009148;
		Exec(ExeHeader,1,0);
	}
	printf("No boot file !\n");
	while (1) ;
}
	
/* 0xbfc03c90 */
int ReadExeHeader(int fd,void *buf)
{
	if (read(fd , Buffer , 2048) <2048) {
		return 0;
	}
	memcpy(buf , &Buffer[0x10] , 0x3c);
	return 1;
}


/* sys_a0_43 0xbfc03cf0 */
int Exec(struct EXEC *exe , int argc , char **argv)
{
	int i;
	long *p;

	exe->SavedS0 = _s0_;
	exe->SavedRA = _ra_;
	exe->SavedSP = _sp_;
	exe->SavedS8 = _s8_;
	exe->SavedGP = _gp_;
	if (exe->b_size) {
		p = exe->b_addr;
		for (i = exe->b_size ; i > 0 ; i -= 4) {
			*p++ = 0;
		}
	}
	if (exe->s_addr) {
		_stk_ = exe->s_addr + exe->s_size;
		_fp_ = _stk_;
	}
	_gp_ = exe->gp0;
	(exe->pc0)(argc , argv);
	_ra_ = exe->SavedRA;
	_sp_ = exe->SavedSP;
	_s8_ = exe->SavedS8;
	_gp_ = exe->SavedGP;
	_s0_ = exe->SavedS0;

	return 1;
}


/* 0xbfc03d80 */
GPU_dw(x,y,w,h,*data)
{
	int count;

	count = 16;
	while (!(*gp1 & 0x04000000)) {
		if (! count--) {
			printGPUtimeout("GPU_dw");
		}
	}
	*gp0 = 0xa0000000;
	*gp0 = (y<<16)|(x&0xffff);
	*gp0 = (h<<16)|(y&0xffff);

	count = (w*h)/2-1;
	if (count==-1) return;
	do {
		*gp0 = *data++;
	} while(count--);
}

printGPUtimeout(char* str) // bfc04260
{
	printf("%s timeout: gp1=%08x",str,*gp1);
}


GPU_cw(u_long c)
{
	GPU_sync();
	*gp0=c;
}


bfunc40ec()
{
	*d2_chcr=0x0401;
	*gp1=0x04000000;
	*gp1=0x02000000;
	*gp1=0x01000000;
}

// download from gp0
bfunc3fe0(u_long a0, u_long a1)
{
	GPU_sync();
}


SendPrimitives(void* ptr) // bfc0403c
{
	printf("0x01(%08x)\n",ptr);
	GPU_sync();

	*gp1=0x04000002;

	*d_icr=0;
	*d_pcr|=0x0800;

	*d2_madr=ptr;
	*d2_bcr=0;
	printf("0x02\n");

	*d2_chcr=0x01000401;
	printf("0x03\n");
}

/* 0xbfc04610 */
InitIntr(int count)
{
	u_char *p;
	u_long size;
	size=count * 8;
	if ((p=_SysMalloc(size))==NULL) {
		return 0;
	}
	bclear(p, size);
	*(u_long *)0xa0000100=p;
	*(u_long *)0xa0000104=size;
	return size;
}

/* 0xbfc04678 */
InitEvent(int n) {
	int i;
	unsigned long *h, *p;
	printf("\nConfiguration : EvCB\0100x%02x\010\010", n);
	i=n;
	n *=28;
	if ((h=_SysMalloc(n))== NULL) {
		return 0;
	}
	*(u_long *)0xa0000124=n;
	*(u_long *)0xa0000120=h;
	for (p=h ; p < (EvCB *)(h + n) ; p++) {
		*p=0;
	}
	return n;
}


/* sys_a0_9f 0xbfc06680 */
SetMem(size)
{
	int *mem,new;
	mem=*ram_size;
	new=*mem & 0xfffff8ff;
	switch(size) {
	case 2:
		*mem=new;
		*(long *)(0x00000060)=size;
		printf("Change effective memory : %d MBytes\n",size);
		break;
	case 8:
		*mem=new | 0x300;
		*(long *)(0x00000060)=size;
		printf("Change effective memory : %d MBytes\n",size);
	default:
		printf("Effective memory must be 2/8 MBytes\n");
		break;
	}
}


/* 0xbfc06700 */
do_a_long_jump(int value) {
	longjmp(&context,value);
}


/* sys_a0_9d 0xbfc06728 */
GetConf(long *Event,long *TCB,long *Stack)
{
	*Stack=sys_conf.Stack;
	*Event=sys_conf.Event;
	*TCB=sys_conf.TCB;
}


/* sys_a0_9c 0xbfc06750 */
SetConf(long Event,long TCB,long Stack)
{
	sys_conf.Stack=Stack;
	sys_conf.Event=Event;
	sys_conf.TCB=TCB;
	_kernel_setup();
}

/* 0xbfc06784 */
part3() {
	char s1[80],s2[80];

	strcpy(s2,"cdrom:");
	strcat(s2,"SYSTEM.CNF;1");
	strcpy(s1,"cdrom:");
	strcat(s1,"PSX.EXE;1");
	bootstrap(s2,s1);
}

/* 0xbfc067e8 */
bootstrap(char *config,char *executable)
{
	int fd,readen;

	__trace(1);
	setSTATUS(getSTATUS() & 0xfffffbfe);
	zero_stuff();
	__trace(2);
	SysInitKMem();
	__trace(3);
	InstallInterruptTables();
	InstallInterruptDispatch();
	PatchA0Table();
	InstallExceptionHandler();
	ResetEntryInt();
	__trace(4);
	zero_stuff();
	IntrMask=0;
	*i_reg=0;
	InstallDevices(_0xa000b9b0);
	__trace(5);
	printf("\nPS-X Realtime Kernel Ver.2.5\n \ Copyright 1993,1994 (C) Sony Computer Entertainment Inc. \n");
	__trace(6);
	zero_stuff();
	memcpy(&sys_conf , &default_sys_conf , 12);
	printf("KERNEL SETUP!\n");
	SysInitMemory(0xa000e000 , 0x2000);
	InitIntr(4);
	InitException(0);
	InitDefInt(3);
	InitEvent(sys_conf.Event);
	InitSchr(1,sys_conf.TCB);
	InitRCnt(1);
	zero_stuff();
	if (setjmp(&context))
		sys_err(0x0385);
	__trace(7);
	ExecuteShell();
	/* this is where the country lockout is located */
	__trace(8);
	IntrMask=0;
	*i_reg=0;
	_96_init();
	if (setjmp(&context))
		sys_err(0x0399);
	if (CheckForDevice1()== 1)
		InitDevice1();
	printf("\nBOOTSTRAP LOADER Type C Ver 2.1 03-JUL-1994\n\ Copyright 1993,1994 (C) Sony Computer Entertainment Inc.\n");
	if (setjmp(&context))
		sys_err(0x0386);
	__trace(9);
	if (setjmp(&context))
		sys_err(0x387);
	if ((fd=open(config , 1))>= 0) {
		printf("setup file    : %s\n",config);
		if (setjmp(&context))
			sys_err(0x038f);
		if ( (readen = read(fd , Buffer , 2048)) == 0) {
			memcpy(&sys_conf , &default_sys_conf , 12);
			strcpy(BootFile , executable);
		} else {
		    	Buffer[readen] = (char) 0;
			close(fd);
			if (setjmp(&context))
				sys_err(0x0390);
			ParseSetupFile(Buffer , sys_conf , BootFile);
		}
	} else {
		if (setjmp(&context))
			sys_err(0x0391);
		_0x00000180 = (char)0;
		memcpy(&sys_conf , &default_sys_conf , 12);
		strcpy(BootFile , executable);
	}
	if (setjmp(&context))
		sys_err(0x0388);
	kernel_setup();
	printf("boot file     : %s\n",BootFile);
	if (setjmp(&context))
		sys_err(0x0389);
	ClearRam();
	if (Load(BootFile,ExeHeader))
		sys_err(0x038a);
	printf("EXEC:PC0(%08x)  T_ADDR(%08x)  T_SIZE(%08x)\n",
		ExeHeader.pc0 , ExeHeader.t_addr , ExeHeader.t_size);
	printf("boot address  : %08x %08x\nExecute !\n\n",
		ExeHeader.pc0 , sys_conf.Stack);
	_0xa000b890 = sys_conf.Stack;
	_0xa000b894 = 0;
	printf("                S_ADDR(%08x)  S_SIZE(%08x)\n",
		sys_conf.Stack , 0);
	EnterCriticalSection();
	if (setjmp(&context))
		sys_err(0x038b);
	doExec(ExeHeader,1,0);
	printf("End of Main\n");
	sys_err(0x038c);
}

/* 0xbfc06f28 */
kernel_setup()
{
	printf("KERNEL SETUP!\n");
	SysInitMemory(0xa000e000 , 0x2000);
	InitIntr(4);
	InitException(0);
	InitDefInt(3);
	InitEvent(sys_conf.Event);
	InitSchr(1,sys_conf.TCB);
	InitRCnt(1);
	_96_init();
}

part2()
{
	__trace(0x0f);
	zero_stuff();
	if (CheckForDevice2() == 1)
		InitDevice2();
	__trace(0x0e);
	_0xa000b9b0 = 0;
	part3();
}

/* 0xbfc06ff0 */
ExecuteShell(long arg)
{
	memcpy(0x80030000 , 0xbfc18000 , 0x67ff0);
	FlushCache();
	(char *)(0x80030000)(arg);
}

/* 0xbfc0703c */
CheckForDevice2()
{
	char *src,*dst;

	src = License;
	dst = 0x1f000084;
	
	if (License[0]) {
		while (src) {
			if (*src++ != *dst++) break;
		}
	}
	if (*src)
		return 0;
	else
		return 1;
}

/* 0xbfc070ac */
CheckForDevice1()
{
	char *src,*dst;

	src = License;
	dst = 0x1f000004;
	
	if (License[0]) {
		while (src) {
			if (*src++ != *dst++) break;
		}
	}
	if (*src)
		return 0;
	else
		return 1;
}

/* 0xbfc0711c */
InitDevice2()
{
	(char *)(0x1f000080)();
}

0xbfc07148() /* */
{
	printf("PIO SHELL for PlayStation(tm)\n");
	printf("%s\n",0x1f000004);
	(char *)(0x1f000000)();
}

/* 0xbfc071a0 */
OpenCDEvents()
{
	sys_a0_a2();
	event_cd_ack   = OpenEvent(0xf0000003 , 0x10 , 0x2000 , 0);
	event_cd_comp  = OpenEvent(0xf0000003 , 0x20 , 0x2000 , 0);
	event_cd_dr    = OpenEvent(0xf0000003 , 0x40 , 0x2000 , 0);
	event_cd_de    = OpenEvent(0xf0000003 , 0x80 , 0x2000 , 0);
	event_cd_error = OpenEvent(0xf0000003 , 0x8000 , 0x2000 , 0);
	EnableEvent(event_cd_ack);
	EnableEvent(event_cd_comp);
	EnableEvent(event_cd_dr);
	EnableEvent(event_cd_de);
	EnableEvent(event_cd_error);
	ExitCriticalSection();
	_0xa0009d80 = (char)0;
}

0xbfc07330()
{
	OpenCDEvents();
	while (!sys_a0_95()) ;
}


/* 0xbfc073a0 */
_96_init()
{
	long tmp;

	0xbfc07330();
	tmp = 0;
	while (tmp <50000) {	/* this loop might be stupid, but its */
		tmp=tmp;	/* what it does */
		tmp++;
	}
	dev_cd_initfs();
}

/* 0xbfc0c720 */
Test6ButtonPad()
{
	/* Would u believe me if i told u that */
	u_long tmp; /* this and a lot more routines are */
	u_long paddata; /* NEVER called ? */
	printf("test 6 button PAD (NEW)\n");
	if (!PAD_init(0x20000001 , &paddata)) return;
	while (1) {
		tmp=0x000186a0;
		for (i=0 ; i < tmp; i++ ) {
			i=i; /* burn some cycles */
		}
		tmp=PAD_dr();
		EnterCriticalSection();
		printf("ret:%08x stock:",tmp); printf(" %08x",paddata);
		printf("\n");
		ExitCriticalSection();
	}
}

/* 0xbfc0d4cc */
EnableIORedirection()
{
	AddDrv(&tty_redir);	/* 0xbfc0e59c */
}

/* 0xbfc0d570 */
doExec(struct EXEC *exeheader,long arg1,long arg2)
{
	ExitCriticalSection();
	if (_0xa000dffc) {
		/* THIS LOOP IS COPYPROTECTION RELATED */
		if (0xbfc0d72c() < 0) {
			/* This routine and the next one, */
			SystemError(0x44 , 0x038b);
		}
		/* does some kind of black or country */
		if (0xbfc0d7bc() < 0) {
			/* check. These are used in the shell */
			SystemError(0x44 , 0x038b);
		} /* also, if they fail, byebye */
	} /* Noping them here or in the shell, wont solve a thing */
	EnterCriticalSection();		/* I hope to have the time someday */
	Exec(exeheader , arg1 , arg2);	/* to write about protections, since */
	/* i know some stuff about. I guided a friend with a DDX, in tracing */
	/* executing some code. He came to the conclusion that these routines */
	/* return different values whether a CD is audio, psx original, psx */
	/* foreign, or gold/HK. Hope to write about it soon */
}

/* 0xbfc0d600 */
0xbfc0d600()
{
	*reg0=1;
	*reg3=0x1f;
	for (i=0 ; i !=4 ; i++) {
		*(long *)(0)=i & 3;
	}
}

/* 0xbfc0d640 */
0xbfc0d640()
{
	*reg0=1;
	*reg2=0x1f;
}

/* 0xbfc0d664 */
0xbfc0d664()
{
	*reg0=1;
	*reg2=0x18;
}

/* 0xbfc0d72c */
0xbfc0d72c()
{
	0xbfc0d600();
	0xbfc0d664();
	*reg0=0;
	*reg1=0x1e;
	tmp=0xbfc0d688();
	if (tmp < 0) {
		0xbfc0d640();
		return 1;
	}
	if (tmp & 0x1d) {
		0xbfc0d640();
		return 1;
	}
	0xbfc0d600();
	0xbfc0d640();
	return 0;
}

/* 0xbfc0d850 */
ClearRam() {
	u_long *p,top;

	top=_stk_ | 0xa0000000;
	for (p=0xa0010000 ; p !=top ; p++) {
		*p=0;
	}
}

static char License[]="Licensed by Sony Computer Entertainment Inc." ;
static struct default_sys_conf={ 4, 16, 0x801fff00 }; /* 0xbfc0e14c */
static struct EXEC ExeHeader; /* 0xa000b870 */
static char *BootFile; /* 0xa000b8b0 */
static struct sys_conf { /* 0xa000b940 */
	u_long TCB;
	u_long Event;
	u_long Stack;
};
static jmp_buf context; /* 0xa000b980 */
How to compile this code? PSY-Q gives some errors. Is it compiled on PSXSDK?

Re: PSone BIOS modding project

Posted: June 23rd, 2018, 2:35 am
by Shadow
It's disassembled assembler from the BIOS re-created as C code. It's not compilable. It's just for reference to see how the functions may have looked or worked in C.

Re: PSone BIOS modding project

Posted: June 24th, 2018, 1:24 am
by rama3
Shadow, do you happen to know how that ColorBars() works?
Is it a hardware debug feature? Can it be accessed somehow?

Re: PSone BIOS modding project

Posted: June 24th, 2018, 10:23 am
by Shadow
I'm not sure why the colour bar stuff is in there, but it looks like it was left in there from the development boards. I don't know if it can be accessed, and even if it could, the system would need to be put into a different loop to render them unless they have priority over the other tasks somehow.

Re: PSone BIOS modding project

Posted: June 24th, 2018, 11:52 pm
by rama3
Alright, thanks :)

Re: PSone BIOS modding project

Posted: February 19th, 2022, 11:13 pm
by aarkay14
OK! Sorry necro bumping this thread again, but if we could make a custom bios for the original PSX then it will be AWESOME!!! We can do various stuff with it! I mean for starters remove that ugly menu after the boot with a nice one.

Kind Regards
Rama

Re: PSone BIOS modding project

Posted: February 19th, 2022, 11:27 pm
by CodeAsm
https://problemkaputt.github.io/psx.htm custom faster bios right there :D

and people already piggybacked it or swap the bios here? viewtopic.php?t=1304

But modding the original one would be cool, I like the gray menu alott (not the color randomness one, but just nostalgia i guess)