User:Combuster/Mach64 Hardware
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:
- Disable CRTC output
- Write the CRTC registers
- Enable the CRTC
- 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 |