mac-rom/DeclData/DeclVideo/ATI/Diamond.c

462 lines
13 KiB
C

/*
File: Diamond.c
Contains: xxx put contents here xxx
Written by: xxx put writers here xxx
Copyright: © 1994 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<1> 1/18/94 CP first checked in
*/
/* Diamond.c */
/*
* C Source Code to drive Diamond board
*/
#include <Types.h>
#include <Quickdraw.h>
#include <Types.h>
#include <Errors.h>
#include <OSUtils.h>
#include "ATIStdTypes.h"
#include "ATI.h"
// vclk = 0x4F349B; // supposedly the value for 39.5 MHz (wrong!)
// vclk = 0x47BCB4; // for a (pre-non-divided) dotclock of 30.24 MHz
// vclk = 0x47BC34; // for a (pre-non-divided) dotclock of 60.48 MHz
// vclk = 0x4D8527; // for a (pre-non-divided) dotclock of 17.457 MHz
void GoDiamond640x480x8VGA(UInt8 devID)
{
unsigned long memSize = 0x2000001; // bing
unsigned long depth = 8; // bing
unsigned long rowBytes = (depth >> 3) * 640; // bing
#if 0
// For now, enable slot D on Bandit 0
*(unsigned long *)0xF2800000 = LByteSwap(0x0848); // Tell Bandit which device
PerformPCIHack();
*(unsigned long *)0xF2C00000 = LByteSwap(0x6000000C); // Set VRAM address in PCI base reg
PerformPCIHack();
#endif
IOLongWrite(0xF2800000, (devID << 12) | 4);
*(unsigned char *)(0xF2C00000) = 0x3;
PerformPCIHack();
IOLongWrite(0xF2800000, (devID << 12) | 0x10);
IOLongWrite(0xF2C00000, kDiamondVRAMAddr);
IOLongWrite(0xF2800000, (devID << 12) | 0x14);
IOLongWrite(0xF2C00000, kDiamondIOAddr);
IOLongWrite(kDiamondInterruptEnable, 0x80); // disable interrupts
IOLongWrite(kDiamondRefreshPeriod, 0x186); // rfperiod
IOLongWrite(kDiamondRasMax, 0xFA); // rlmax
IOLongWrite(kDiamondMemConfig, 0x2); // bing
IOLongWrite(kDiamondSysConfig, 0x563000); // bing
SetupDACDiamond(0x45A8BCD0, depth); // bing
// vga 13"
IOLongWrite(kDiamondHorzLength, 0xC7); // bing
IOLongWrite(kDiamondHorzSyncRisingEdge, 0x17); // bing
IOLongWrite(kDiamondHorzBlankRisingEdge, 0x21); // bing
IOLongWrite(kDiamondHorzBlankFallingEdge, 0xC1); // bing
IOLongWrite(kDiamondHorzCounterPreload, 0x00); // bing
IOLongWrite(kDiamondVertLength, 0x20D); // bing
IOLongWrite(kDiamondVertSyncRisingEdge, 0x01); // bing
IOLongWrite(kDiamondVertBlankRisingEdge, 0x19); // bing
IOLongWrite(kDiamondVertBlankFallingEdge, 0x1F9); // bing
// apple timings
#if 0
IOLongWrite(kDiamondHorzLength, 199); // bing
IOLongWrite(kDiamondHorzSyncRisingEdge, 22); // bing
IOLongWrite(kDiamondHorzBlankRisingEdge, 34); // bing
IOLongWrite(kDiamondHorzBlankFallingEdge, 193); // bing
IOLongWrite(kDiamondHorzCounterPreload, 0x00); // bing
IOLongWrite(kDiamondVertLength, 525); // bing
IOLongWrite(kDiamondVertSyncRisingEdge, 2); // bing
IOLongWrite(kDiamondVertBlankRisingEdge, 34); // bing
IOLongWrite(kDiamondVertBlankFallingEdge, 514); // bing
#endif
IOLongWrite(kDiamondVertCounterPreload, 0x00); // bing
IOLongWrite(kDiamondScreenRepaintTiming, 0x1E5); // bing
// Enable sync's out the connector
*(unsigned char *)(0xF20003C4) = 0x12; // for 0x03C5, offset 0x12
*(unsigned char *)(0xF20003C5) |= 0x10; // bit 4
IOLongWrite(kDiamondPlaneMask, 0xFF);
IOLongWrite(kDiamondDrawMode, 0xA);
// write X and Y minimum (both equal 0)
IOLongWrite(kDiamondWindowMinimum, 0);
// write X maximum (rowBytes - 1) and Y maximum (memSize/rowBytes - 1)
IOLongWrite(kDiamondWindowMaximum,
((rowBytes - 1) << 16) | ((memSize / rowBytes) - 1));
IOLongWrite(0xF2800000, (devID << 12) | 4);
*(unsigned char *)(0xF2C00000) = 0x02;
PerformPCIHack();
}
void GoDiamond640x480x8Apple(UInt8 devID)
{
unsigned long memSize = 0x2000001; // bing
unsigned long depth = 8; // bing
unsigned long rowBytes = (depth >> 3) * 640; // bing
#if 0
// For now, enable slot D on Bandit 0
*(unsigned long *)0xF2800000 = LByteSwap(0x0848); // Tell Bandit which device
PerformPCIHack();
*(unsigned long *)0xF2C00000 = LByteSwap(0x6000000C); // Set VRAM address in PCI base reg
PerformPCIHack();
#endif
IOLongWrite(0xF2800000, (devID << 12) | 4);
*(unsigned char *)(0xF2C00000) = 0x3;
PerformPCIHack();
IOLongWrite(0xF2800000, (devID << 12) | 0x10);
IOLongWrite(0xF2C00000, kDiamondVRAMAddr);
IOLongWrite(0xF2800000, (devID << 12) | 0x14);
IOLongWrite(0xF2C00000, kDiamondIOAddr);
SetupDACDiamond(0x47BCB4D0, depth); // bing
IOLongWrite(kDiamondMemConfig, 0x2); // bing
IOLongWrite(kDiamondSysConfig, 0x563000); // bing
// apple 13"
IOLongWrite(kDiamondHorzSyncRisingEdge, 15); // bing
IOLongWrite(kDiamondHorzBlankRisingEdge, 39); // bing
IOLongWrite(kDiamondHorzBlankFallingEdge, 199); // bing
IOLongWrite(kDiamondHorzLength, 215); // bing
IOLongWrite(kDiamondHorzCounterPreload, 0x00); // bing
IOLongWrite(kDiamondVertSyncRisingEdge, 3); // bing
IOLongWrite(kDiamondVertBlankRisingEdge, 42); // bing
IOLongWrite(kDiamondVertBlankFallingEdge, 522); // bing
IOLongWrite(kDiamondVertLength, 525); // bing
IOLongWrite(kDiamondVertCounterPreload, 0x00); // bing
IOLongWrite(kDiamondScreenRepaintTiming, 0x1E5); // bing
IOLongWrite(kDiamondDrawMode, 0xA);
IOLongWrite(kDiamondPlaneMask, 0xFF);
// write X and Y minimum (both equal 0)
IOLongWrite(kDiamondWindowMinimum, 0);
// write X maximum (rowBytes - 1) and Y maximum (memSize/rowBytes - 1)
IOLongWrite(kDiamondWindowMaximum,
((rowBytes - 1) << 16) | ((memSize / rowBytes) - 1));
IOLongWrite(0xF2800000, (devID << 12) | 4);
*(unsigned char *)(0xF2C00000) = 0x02;
PerformPCIHack();
}
static void SetupDACDiamond(unsigned long vclk, unsigned long depth)
{
short i;
unsigned char *writeReg;
unsigned char *dataReg;
unsigned char cursorCmd;
unsigned char vp, hp; // vertical/horizontal sync polarity
unsigned char getThisDone;
*(unsigned char *)(kBT485Reg0) = 0x82; // 8 bit operation (intead of 6)
PerformPCIHack();
*(unsigned char *)(kBT485Reg2) = 0x30; // PCLK1; data from 32 bit port
PerformPCIHack();
*(unsigned char *)(kRamWrite) = 0x01; // enable command register 3 access
PerformPCIHack();
cursorCmd = (vclk & 0x20) ? 0x08 : 0;
*(unsigned char *)(kBT485Reg3) = cursorCmd;
PerformPCIHack();
switch(depth) {
case 8:
// set DAC into 8 bits per pixel
*(unsigned char *)(kBT485Reg1) = 0x40;
break;
case 16:
// set DAC into 16 bits per pixel
*(unsigned char *)(kBT485Reg1) = 0x30;
break;
case 24:
case 32:
// set DAC into 24/32 bits per pixel
*(unsigned char *)(kBT485Reg1) = 0x10;
break;
}
PerformPCIHack();
*(unsigned char *)(kPixelMask) = 0xFF; // pixel mask register
PerformPCIHack();
// setup up clock bits
vp = (vclk & 0x80) ? NEGATIVE : POSITIVE;
hp = (vclk & 0x40) ? NEGATIVE : POSITIVE;
// Enable sync's out the connector
*(unsigned char *)(0xF20003C4) = 0x12; // for 0x03C5, offset 0x12
getThisDone = *(unsigned char *)0xF20003C5;
PerformPCIHack();
*(unsigned char *)(0xF20003C5) = getThisDone | 0x10;
SetupClockDiamond(vclk >> 8);
#if 0
SetupClockDiamond(0x65D83D); // mem clock = 25Mhz
SetupClockDiamond(0x67B83C);
#endif
SetupClockDiamond(vclk >> 8);
#if 0
*(unsigned char *)(0xF20003C2) = (ReadClockReg()) | (hp << 6) | (vp << 7);
#endif
// a magic number: set bits 6 and 7 to 0 for negative sync polarity
*(unsigned char *)(0xF20003C2) = 0xC;
PerformPCIHack();
if (depth == 8) {
writeReg = (unsigned char *)(0xF20003C8); // kRamWrite
dataReg = (unsigned char *)(0xF20003C9); // kPaletteData
*writeReg = 0;
PerformPCIHack();
for (i = 0; i < 256; i++) {
*dataReg = i; // red
PerformPCIHack();
*dataReg = i; // green
PerformPCIHack();
*dataReg = i; // blue
PerformPCIHack();
}
}
}
unsigned char ReadClockReg(void)
{
unsigned char *ClockSelReg = (unsigned char *)(0xF20003C2);
unsigned char ret;
ret = (*(ClockSelReg + 0xA)); // 0x03C2 is really read from 0x03CC
PerformPCIHack();
return ret;
}
void WriteClockReg(unsigned char whatever, unsigned char serialData, unsigned char serialClock)
{
unsigned char *ClockSelReg = (unsigned char *)(0xF20003C2);
*ClockSelReg = (whatever | (serialData << 3) | (serialClock << 2));
PerformPCIHack();
}
void SetupClockDiamond(unsigned long vclk)
{
short x;
unsigned char whatever;
// Read the current clock reg value to save off bits [7..4] and [1..0]
whatever = ReadClockReg() & 0xF3;
// unlock the clock chip
WriteClockReg(whatever, 1, 1); // Raise the Data bit and the clock bit
for (x = 0; x < 5; x++)
{
WriteClockReg(whatever, 1, 0); // Lower the clock
WriteClockReg(whatever, 1, 1); // Raise the clock
}
// Finish Unlocking
WriteClockReg(whatever, 1, 0);
WriteClockReg(whatever, 0, 0);
WriteClockReg(whatever, 0, 1);
// Start bits
WriteClockReg(whatever, 0, 0); // Clock: hi-lo
WriteClockReg(whatever, 0, 1); // Clock: lo-hi
// Manchester encoding:
// Set SerialData to !vclk[0]; Drop SerialClk to 0; Set SerialData to vclk; Set SerialClock to 1
for (x = 0; x < 24; x++)
{
// write out the inverse of the vclk bit
WriteClockReg(whatever, (vclk & 1) ? 0 : 1, 1);
WriteClockReg(whatever, (vclk & 1) ? 0 : 1, 0);
// write out the vclk bit
WriteClockReg(whatever, (vclk & 1) , 0);
WriteClockReg(whatever, (vclk & 1) , 1);
vclk >>= 1;
}
// Stop bits
WriteClockReg(whatever, 1, 1);
WriteClockReg(whatever, 1, 0);
WriteClockReg(whatever, 1, 1);
}
void GoDiamond640x480x8AppleOld(UInt8 devID);
void GoDiamond640x480x8AppleOld(UInt8 devID)
{
unsigned char *clutData;
unsigned char *clutAddrReg;
unsigned char cursorCmd;
int i;
IOLongWrite(0xF2800000, (devID << 12) | 4);
*(unsigned char *)(0xF2C00000) = 0x3;
PerformPCIHack();
IOLongWrite(0xF2800000, (devID << 12) | 0x10);
IOLongWrite(0xF2C00000, kDiamondVRAMAddr);
IOLongWrite(0xF2800000, (devID << 12) | 0x14);
IOLongWrite(0xF2C00000, kDiamondIOAddr);
// Configure memory space appropriately
IOLongWrite( kDiamondMemConfig, 0x2);
// IOLongWrite( kDiamondSysConfig, (0x6 << 17) | (1 << 13) | (1 << 12));
IOLongWrite( kDiamondSysConfig, (0x563000)); // RowBytes of 640 hardcoded
// Draw Engine parameters
IOLongWrite( kDiamondWindowMinimum, 0);
IOLongWrite( kDiamondWindowMaximum, (639 << 16) | ((0x2000001 / 640) - 1));
IOLongWrite( kDiamondScreenRepaintTiming, 0x1E5);
*(unsigned char *)(0xF2009800) = 0x40; // set DAC into 8 bits per pixel
// set to 0x30 for 16 bpp
// set to 0x10 for 32 bpp
PerformPCIHack();
*(unsigned char *)(0xF2009402) = 0x82; // 8 bit operation (instead of 6)
PerformPCIHack();
*(unsigned char *)(0xF2009801) = 0x32; // PCLK1; data from 32 bit port
PerformPCIHack();
*(unsigned char *)(0xF20003C6) = 0xFF; // pixel mask register
PerformPCIHack();
cursorCmd = 0x04 & !0x08; // 64x64 bit cursor;
// disable 2 times clock
*(unsigned char *)(0xF20003C8) = 0x01; // enable command register 3 access
PerformPCIHack();
*(unsigned char *)(0xF2009802) = cursorCmd;
PerformPCIHack();
clutAddrReg = (UInt8 *)(0xF20003C8); // Point to write-index register
clutData = (UInt8 *)(0xF20003C9); // Point to data register
*clutAddrReg = 0; // Point to the first entry
for ( i = 0; i < 256; i++ ) {
*clutData = i;
PerformPCIHack();
*clutData = i;
PerformPCIHack();
*clutData = i;
PerformPCIHack();
}
// SetupClockW9000();
{
unsigned long data = 0x47BCB4; // for a (pre-non-divided) dotclock of 30.24 MHz
short x;
unsigned char whatever;
// Read the current clock reg value to save off bits [7..4] and [1..0]
whatever = ReadClockReg() & 0xF3;
// unlock the clock chip
WriteClockReg(whatever, 1, 1); // Raise the Data bit and the clock bit
for (x = 0; x < 5; x++)
{
WriteClockReg(whatever, 1, 0); // Lower the clock
WriteClockReg(whatever, 1, 1); // Raise the clock
}
// Finish Unlocking
WriteClockReg(whatever, 1, 0);
WriteClockReg(whatever, 0, 0);
WriteClockReg(whatever, 0, 1);
// Start bits
WriteClockReg(whatever, 0, 0); // Clock: hi-lo
WriteClockReg(whatever, 0, 1); // Clock: lo-hi
// Manchester encoding:
// Set SerialData to !data[0]; Drop SerialClk to 0; Set SerialData to data; Set SerialClock to 1
for (x = 0; x < 24; x++)
{
// write out the inverse of the data bit
WriteClockReg(whatever, (data & 1) ? 0 : 1, 1);
WriteClockReg(whatever, (data & 1) ? 0 : 1, 0);
// write out the data bit
WriteClockReg(whatever, (data & 1) , 0);
WriteClockReg(whatever, (data & 1) , 1);
data >>= 1;
}
// Stop bits
WriteClockReg(whatever, 1, 1);
WriteClockReg(whatever, 1, 0);
WriteClockReg(whatever, 1, 1);
// Enable sync's out the connector
*(unsigned char *)(0xF20003C4) = 0x12; // for 0x03C5, offset 0x12
*(unsigned char *)(0xF20003C5) |= 0x10; // bit 4
}
IOLongWrite( kDiamondHorzSyncRisingEdge, 15);
IOLongWrite( kDiamondHorzBlankRisingEdge, 39);
IOLongWrite( kDiamondHorzBlankFallingEdge, 199);
IOLongWrite( kDiamondHorzLength, 215);
IOLongWrite( kDiamondVertSyncRisingEdge, 3);
IOLongWrite( kDiamondVertBlankRisingEdge, 42);
IOLongWrite( kDiamondVertBlankFallingEdge, 522);
IOLongWrite( kDiamondVertLength, 525);
IOLongWrite(0xF2800000, (devID << 12) | 4);
*(unsigned char *)(0xF2C00000) = 0x2;
PerformPCIHack();
}