S3 ViRGE 2D driver

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

S3 ViRGE 2D driver

Post by blackoil »

hi

I am ready *all day long* to implement it with BitBlt functionality. I got xf86-video-s3virge-1.10.4.zip.
Does anyone have done this before? any hint?

Code: Select all

W3D4(0x38,0x48); //unlock
W3D4(0x39,0xa5); //unlock

W3D4(0x40,R3D4(0x40)|0x1); //enable ext. reg
W3D4(0x53,R3D4(0x53)|0x8); //enable mmio

W3D4(0x59,videoaddr>>24); //linear addr
W3D4(0x5A,videoaddr>>16); //linear addr

W3D4(0x66,0x89); //enabel gfx engine
W3D4(0x63,0x10); //set display fifo
PCICFG bar0 is 0xF8000000
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: S3 ViRGE 2D driver

Post by Combuster »

If you know where to look, the actual writes are pretty straightforward as they all take a common format: Wait for the device, then pump some commands. Which is not much different from the many other video cards from that period.

As a general tour of reverse engineering basics an example of the reset code:

Code: Select all

/* s3v_accel.c:492 */
    WAITFIFO(5);
    OUTREG(SRC_BASE, 0);
    OUTREG(DEST_BASE, 0);
    OUTREG(DEST_SRC_STR, ps3v->Stride | (ps3v->Stride << 16));
You could have looked up the relevant macros:

Code: Select all

/* s3v.h:91 */
#define OUTREG(addr, val) MMIO_OUT32(ps3v->MapBase, addr, val)
which tells us that the default register is 32 bits and is located at a certain offset from MapBase:

Code: Select all

/* s3v_driverc:2182 */
  ps3v->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, ps3v->PciTag,
				PCI_REGION_BASE(ps3v->PciInfo, 0, REGION_MEM) + S3_NEWMMIO_REGBASE,
				S3_NEWMMIO_REGSIZE);
which maps regsize bytes from BAR + regbase. In essence the MMIO comes directly after the possible video RAM but otherwise shares a base address register.

Code: Select all

/* newmmio.h:48 */
#define S3_NEWMMIO_REGBASE	0x1000000  /* 16MB */
#define S3_NEWMMIO_REGSIZE	  0x10000  /* 64KB */
You know the offset:

Code: Select all

/* s3v_macros.h:73 */
#define SRC_BASE	0xA4D4
#define DEST_BASE	0xA4D8
so altogether a write goes to BAR + REGBASE + (offset). Performing the same strategy with the value part will allow you to replicate the writes an X.org driver would perform, and all I really did so far was just a multi-file search for definitions or the relevant setters.

Now you do the same for the functions in s3v_accel.h that you want to use. You probably want to start with fills or screen-to-screen blits because you can visually inspect the results.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

Re: S3 ViRGE 2D driver

Post by blackoil »

yes, i know how to make a mmio write. but nothing happened.

Code: Select all

/* Subsystem Control Register */
#define	GPCTRL_NC	0x0000
#define	GPCTRL_ENAB	0x4000
#define	GPCTRL_RESET	0x8000


/* Command Register */
#define	CMD_OP_MSK	(0xf << 27)
#define	CMD_BITBLT	(0x0 << 27)
#define	CMD_RECT       ((0x2 << 27) | 0x0100)
#define	CMD_LINE	(0x3 << 27)
#define	CMD_POLYFILL	(0x5 << 27)
#define	CMD_NOP		(0xf << 27)

/* Command AutoExecute */
#define CMD_AUTOEXEC	0x01

/* Command Hardware Clipping Enable */
#define CMD_HWCLIP	0x02

/* Destination Color Format */
#define DST_8BPP	0x00
#define DST_16BPP	0x04
#define DST_24BPP	0x08

/* BLT Mix modes */
#define	MIX_BITBLT	0x0000
#define	MIX_MONO_SRC	0x0040
#define	MIX_CPUDATA	0x0080
#define	MIX_MONO_PATT	0x0100
#define MIX_COLOR_PATT  0x0000
#define	MIX_MONO_TRANSP	0x0200

/* Image Transfer Alignments */
#define CMD_ITA_BYTE	0x0000
#define CMD_ITA_WORD	0x0400
#define CMD_ITA_DWORD	0x0800

/* First Doubleword Offset (Image Transfer) */
#define CMD_FDO_BYTE0	0x00000
#define CMD_FDO_BYTE1	0x01000
#define CMD_FDO_BYTE2	0x02000
#define CMD_FDO_BYTE3	0x03000

/* X Positive, Y Positive (Bit BLT) */
#define CMD_XP		0x2000000
#define CMD_YP		0x4000000

Code: Select all

uint[512]*   mmio;

mmio=videoaddr+0x01000000;
                                    //SOLID FILL SETUP
(*mmio) [PAT_FG_CLR/4] = 1235678;
(*mmio) [MONO_PAT_0/4] = ~0;
(*mmio) [MONO_PAT_1/4] = ~0;
(*mmio) [CMD_SET/4] = CMD_AUTOEXEC;

Code: Select all

uint[512]*   mmio;

mmio=videoaddr+0x01000000;
                                      // SOLID FILL
(*mmio) [RWIDTH_HEIGHT/4] = (w<<16)|h;
(*mmio) [RSRC_XY/4] = (srcx<<16)|srcy;
(*mmio) [RDEST_XY/4] = (destx<<16)|desty;
I wonder if I have initialized the chip fully & properly. I have to make the gfx engine ready to work.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: S3 ViRGE 2D driver

Post by Combuster »

Code: Select all

uint[512]*   mmio;
I get a syntax error on that, and you are apparently doing a double dereference.
Last edited by Combuster on Fri May 06, 2011 5:08 am, edited 1 time in total.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

Re: S3 ViRGE 2D driver

Post by blackoil »

ah sorry , i have my own c-ish compiler, that means uint (*mmio)[512];
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: S3 ViRGE 2D driver

Post by Combuster »

I can't get the right address in there without some serious typecasting work. Have you verified it is correct and not multiplied as the type system would normally demand?

Also, I don't see the reset code anywhere...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

Re: S3 ViRGE 2D driver

Post by blackoil »

the statements are ok for my compiler.

Code: Select all

void   S3Reset()
{
uint[512]* mmio;

mmio = videoaddr + 0x01000000;

(*mmio) [SRC_BASE/4] = 0;
(*mmio) [DEST_BASE/4] = 0;
(*mmio) [DEST_SRC_STR/4] = 640*4;
(*mmio) [CLIP_L_R/4] = 0 | 640;
(*mmio) [CLIP_T_B/4] = 0 | 480;
}

Code: Select all

void  S3Init()
{
OutPortB(0x3C3,(UINT)InPortB(0x3C3) | 1); //enable vga
OutPortB(0x3C2,(UINT)InPortB(0x3CC) | 1); //i/o addr select

W3D4(0x38,0x48); //unlock
W3D4(0x39,0xa5); //unlock

W3D4(0x40,R3D4(0x40)|0x1); //enable ext. reg
W3D4(0x53,R3D4(0x53)|0x8); //enable mmio
W3D4(0x58,R3D4(0x58)|0x3|0x10); //linear addr window

W3D4(0x59,videoaddr>>24); //linear addr
W3D4(0x5A,videoaddr>>16); //linear addr

W3D4(0x66,0x89); //enable gfx engine
W3D4(0x63,0x10); //set display fifo
}
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

Re: S3 ViRGE 2D driver

Post by blackoil »

I have added the DRAW | DST_24BPP flags in the fillsetup function, but still nothing happened.

I suspect the chip is not ready.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: S3 ViRGE 2D driver

Post by Combuster »

Still no good copy...
OUTREG(DEST_SRC_STR, ps3v->Stride | (ps3v->Stride << 16));
And for the sake of it: I assume plotting pixels manually does work?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

Re: S3 ViRGE 2D driver

Post by blackoil »

there is a function S3VGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file);

It's a little complex.
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

Re: S3 ViRGE 2D driver

Post by blackoil »

oh yeah!!!

something changed on screen.

THANKS! Combuster

Code: Select all

void   S3Reset()
{
uint[512]* mmio;

mmio = videoaddr + 0x01000000;

(*mmio) [SRC_BASE/4] = 0;
(*mmio) [DEST_BASE/4] = 0;
(*mmio) [DEST_SRC_STR/4] = 640*3 | ( (640*3)<<16 );
(*mmio) [CLIP_L_R/4] = 0 | 640;
(*mmio) [CLIP_T_B/4] = 0 | 480;
}
Post Reply