mac-rom/DeclData/DeclVideo/ATI/Diamond.c
Elliot Nunn 0ba83392d4 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-09-20 18:04:16 +08:00

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();
}