User:Combuster/Mach64 Hardware

From OSDev Wiki
Jump to navigation Jump to search

Below you'll find the notes on my reverse engineering tours on the mach64 hardware. Don't expect it to be complete.

The Mach64 is an old, yet widely spread graphics chip that supports high resolution modes, 2D hardware acceleration, and on later versions, accelerated 3D operations. It can be found in many older computers (Pentium 1 till Pentium 3 era) as popular onboard graphics chips, although there are plugin cards and laptop versions available.

Introduction to this document

Since documentation is scarce and implementations rare, I write most of this based on personal experience. Expect that the information will still be incomplete, but at least slightly more helpful than the code found on the web.

I have four variants, I generally test on three of them since the fourth is bios-disabled for a different graphics card.

I have: Rage Pro Turbo Rage IIC Rage XL 264VT (the disabled one)

All Mach64s labeled 'Rage' are generations of the 264GT I do not have some older chips that do belong to this family: 88800 chips 264CT chips

Most notably, I only have PCI based devices and therefore can't tell much about the older ISA ones. However, the only other doc around (i.e. VGADOC) is mainly concerned about the ISA variants, although still necessary for all the standard register locations.

Guided Tour

Hop on the bus and get to know the Mach64 family.

Detection

There are several methods of detecting a Mach64. The most straightforward one is to have a look at the PCI devices, and see if there's a good chip present. Should you find one, then you should really check out its BARs - it normally has three of them. The first is the offset of the linear framebuffer, the second is the offset of the port I/O range, while the third is a memory-mapped range. Although normally present, people believe that it has sometimes been missing in action.

todo: list PCI ids and corresponding information

The second method (especially interesting for ISA devices and other ATI devices) works by poking around video BIOS. ATI always put a header on top of their video bios that, among others, tell what kind of device it is. Even now you can still use it to detect a newer Radeon without doing potentially dangerous probes.

What we know from here is where we can find the framebuffer. If you want to play around, you can try writing here as it works in VGA modes as well, minus the nuisance called planes as everything's available as 256k of memory and then some. (the planes are interleaved. every doubleword matches one address in planar memory: byte 0 plane 0, byte 0 plane 1, byte 0 plane 2, byte 0 plane 3, byte 1 plane 0, byte 1 plane 1, ...)

Enabling the chip

Lets have a chat with the device. If you paid attention you should have gotten the second BAR from the PCI space. If you paid even more attention then you'd know that ISA devices are accessed differently.

At least for PCI you add the register number times four (= register offset) to the base address you have and you can do 32-bit reads and writes off there.

What's the case is that the Mach64 is pretending that it is a VGA card. This is nice for every beginner which just wants to see it work, but not when we want to get more out of it.

Let us start by disabling the VGA frontend and have it show its true nature.

uint32_t oldvalue;
oldvalue = inportd(port_base + CRTC_GEN_CNTL);
oldvalue |= CRTC_EXT_DISP_EN;
outportd(port_base + CRTC_GEN_CNTL, oldvalue);

Notice how the screen blinks and presents you with some nice colors.

What you can do here is write to the framebuffer and draw some nice graphical images across the screen.

All shapes and colours

You may have figured that you miss some information about the screen to write to it properly. Of course, we haven't set the resolution yet. Or actually, we might have. When the Mach64 emulates the VGA, the registers are mirrored. So when we put the 'VGA' Mach64 into text mode, we set the resolution to an equivalent of 720x400. So when we enabled the Mach64, it will still display 720x400, still 256 colors since that's what the VGA can do, but only graphics mode since that too, is a thing of the VGA.

Todo: tell about timing

When we know what resolution we want to set, we can tell the Mach64 about it. It however doesn't like to be told how to do things when it is busy doing differently, so it must be turned off to make sure its calm and willing.

So the steps are:

  1. Disable CRTC output
  2. Write the CRTC registers
  3. Enable the CRTC
  4. Enjoy life.


The wristwatch and the work schedule

Hey look! The mach64 is intelligent, and it will buffer large bits of memory into a local buffer before displaying it. Since it can do burst transactions that way it occupies the bus for less time than it might have done otherwise.

The elderly have automated this task and will automatically fetch a new set when they are running short of data. The younger rage chips however have this nice DSP which tell when to load image data from memory. If it forgets to load data, it will stutter and repeat whatever it still remembers, which is generally not quite what you want.

todo: this is where the horror starts

Code snippets

Rage IIC register image

The undocumented stuff returns. You need to set a clock (undocumented) besides switching to the accelerator CRTC (documented) or you'll be left with a garbled display.

    crtcgenctl = &HB010200

    ' kill CRTC
    outportd(portbase + mach64_regs.CRTC_GEN_CNTL, crtcgenctl and (not Mach64_crtc_gen_cntl.CRTC_EN) )

    ' write registers
    outportd(portbase + &H14, &H14000000)
    outportd(portbase + &H20, &H460756)
    outportd(portbase + &H24, &H900714)
    outportd(portbase + &H90, &Had0003)

    ' enable CRTC
    outportd(portbase + mach64_regs.CRTC_GEN_CNTL, crtcgenctl)

this isn't much of a documentation but I haven't got much more than this for now.


Various mach64 chips and their features

todo: determine if fifo size is bits or bytes, figure the difference in 3d engines

Chip Name Identifier pixel clock mem clock chip clock std. pll/dac DSP 3D other (see linux sources)
ATI888GX00 (Mach64 GX) ? 135 MHz 50 MHz 50 MHz No No No ATI_CHIP_88800GX
ATI888CX00 (Mach64 CX) ? 135 MHz 50 MHz 50 MHz No No No ATI_CHIP_88800CX
ATI264CT (Mach64 CT) ? 135 MHz 60 MHz 60 MHz Yes No No ATI_CHIP_264CT
ATI264ET (Mach64 ET) ? 135 MHz 60 MHz 60 MHz Yes No No ATI_CHIP_264ET
ATI264LT (Mach64 LT) ? 135 MHz 63 MHz 63 MHz Yes 24 bit No ATI_CHIP_264LT
ATI264VT (A3) (Mach64 VT) ? Rev 0.0 170 MHz 67 MHz 67 MHz Yes No No ATI_CHIP_264VT
ATI264VT2 (A4) (Mach64 VT) ? Rev 0.1 200 MHz 67 MHz 67 MHz Yes No No ATI_CHIP_264VT + M64F_MAGIC_POSTDIV
ATI264VT (Mach64 VT) ? Rev 0.x 170 MHz 67 MHz 67 MHz Yes No No ATI_CHIP_264VT
ATI264VT3 (B1) (Mach64 VT) ? Rev 1.x 200 MHz 67 MHz 67 MHz Yes 24 bit No ATI_CHIP_264VT3
ATI264VT3 (B2) (Mach64 VT) ? Rev 2.x 200 MHz 67 MHz 67 MHz Yes 24 bit No ATI_CHIP_264VTB
3D RAGE (Mach64 GT) ? Rev x.0 135 MHz 63 MHz 63 MHz Yes No No ATI_CHIP_264GT
3D RAGE II (Mach64 GT) ? Rev x.1 170 MHz 63 MHz 63 MHz Yes 24 bit No ATI_CHIP_264GTB
3D RAGE II+ (Mach64 GT) ? Rev x.2 200 MHz 63 MHz 63 MHz Yes 24 bit No ATI_CHIP_264GTB
ATI264VT3 (Mach64 VU) ? 200 MHz 67 MHz 67 MHz Yes 24 bit No ATI_CHIP_264VT3
3D RAGE II+ (Mach64 GU) ? 200 MHz 67 MHz 67 MHz Yes 24 bit No ATI_CHIP_264GTB
3D RAGE LT (Mach64 LG) ? 230 MHz 63 MHz 63 MHz Yes 24 bit No ATI_CHIP_264LTG + M64F_LT_LCD_REGS + M64F_G3_PB_1024x768
ATI264VT4 (Mach64 VV) ? 230 MHz 83 MHz 83 MHz Yes 24 bit No ATI_CHIP_264VT4
3D RAGE IIC (Mach64 GV, PCI) ? 230 MHz 83 MHz 83 MHz Yes 24 bit No ATI_CHIP_264GT2C
3D RAGE IIC (Mach64 GW, AGP) ? 230 MHz 83 MHz 83 MHz Yes 24 bit No ATI_CHIP_264GT2C
3D RAGE IIC (Mach64 GY, PCI) ? 230 MHz 83 MHz 83 MHz Yes 24 bit No ATI_CHIP_264GT2C
3D RAGE IIC (Mach64 GZ, AGP) ? 230 MHz 83 MHz 83 MHz Yes 24 bit No ATI_CHIP_264GT2C
3D RAGE PRO (Mach64 GB, BGA, AGP) ? 230 MHz 100 MHz 100 MHz Yes 32 bit Yes ATI_CHIP_264GTPRO
3D RAGE PRO (Mach64 GD, BGA, AGP 1x) ? 230 MHz 100 MHz 100 MHz Yes 32 bit Yes ATI_CHIP_264GTPRO
3D RAGE PRO (Mach64 GI, BGA, PCI) ? 230 MHz 100 MHz 100 MHz Yes 32 bit Yes ATI_CHIP_264GTPRO + M64F_MAGIC_VRAM_SIZE
3D RAGE PRO (Mach64 GP, PQFP, PCI) ? 230 MHz 100 MHz 100 MHz Yes 32 bit Yes ATI_CHIP_264GTPRO
3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D) ? 230 MHz 100 MHz 100 MHz Yes 32 bit Yes ATI_CHIP_264GTPRO
3D RAGE LT PRO (Mach64 LB, AGP) ? 236 MHz 75 MHz 100 MHz Yes 32 bit Yes ATI_CHIP_264LTPRO
3D RAGE LT PRO (Mach64 LD, AGP) ? 230 MHz 100 MHz 100 MHz Yes 32 bit Yes ATI_CHIP_264LTPRO
3D RAGE LT PRO (Mach64 LI, PCI) ? 230 MHz 100 MHz 100 MHz Yes 32 bit Yes ATI_CHIP_264LTPRO + M64F_G3_PB_1_1 + M64F_G3_PB_1024x768
3D RAGE LT PRO (Mach64 LP, PCI) ? 230 MHz 100 MHz 100 MHz Yes 32 bit Yes ATI_CHIP_264LTPRO
3D RAGE LT PRO (Mach64 LQ, PCI) ? 230 MHz 100 MHz 100 MHz Yes 32 bit Yes ATI_CHIP_264LTPRO
3D RAGE XL (Mach64 GM, AGP 2x) ? 230 MHz 83 MHz 63 MHz Yes 32 bit Yes ATI_CHIP_264XL
3D RAGE XC (Mach64 GN, AGP 2x) ? 230 MHz 83 MHz 63 MHz Yes 32 bit Yes ATI_CHIP_264XL
3D RAGE XL (Mach64 GO, PCI-66) ? 230 MHz 83 MHz 63 MHz Yes 32 bit Yes ATI_CHIP_264XL
3D RAGE XC (Mach64 GL, PCI-66) ? 230 MHz 83 MHz 63 MHz Yes 32 bit Yes ATI_CHIP_264XL
3D RAGE XL (Mach64 GR, PCI-33) ? 230 MHz 83 MHz 63 MHz Yes 32 bit Yes ATI_CHIP_264XL + M64F_SDRAM_MAGIC_PLL
3D RAGE XC (Mach64 GS, PCI-33) ? 230 MHz 83 MHz 63 MHz Yes 32 bit Yes ATI_CHIP_264XL
3D RAGE Mobility P/M (Mach64 LM, AGP 2x) ? 230 MHz 83 MHz 125 MHz Yes 32 bit Yes ATI_CHIP_MOBILITY
3D RAGE Mobility L (Mach64 LN, AGP 2x) ? 230 MHz 83 MHz 125 MHz Yes 32 bit Yes ATI_CHIP_MOBILITY
3D RAGE Mobility P/M (Mach64 LR, PCI) ? 230 MHz 83 MHz 125 MHz Yes 32 bit Yes ATI_CHIP_MOBILITY
3D RAGE Mobility L (Mach64 LS, PCI) ? 230 MHz 83 MHz 125 MHz Yes 32 bit Yes ATI_CHIP_MOBILITY