private void setMode(int bpp, int refreshRate) {
CirrusVGAState vgaState = new CirrusVGAState(vgaIO);
vgaState.dump();
VesaGTF gtf = VesaGTF.calculate(width, height, refreshRate);
Unsafe.debug("GTF:\n" + gtf.toString() + "\n");
Unsafe.debug("Try to set mode " + width + "x" + height + "@"
+ refreshRate + "Hz\n");
// TODO: disable writeprotect in CR11[7]
// Programm Synthesizer (we use VCLK0)
double value = gtf.getHFrequency() / 14.31818; // Reference clock freq
// in MHz
int denom = 1;
while (value < 128) {
if (value * 2.0 >= 128)
break;
value = value * 2.0;
denom = denom << 1;
}
vgaIO.setSEQ(SRB_VCLK0_NUMERATOR, (int) value);
vgaIO.setSEQ(SR1B_VCLK0_DENOMINATOR_AND_POST_SCALAR, denom << 1);
// finally select VCLK0
vgaIO.setMISC((vgaIO.getMISC() & ~12));
// Programm CRTC
vgaIO.setCRT(CR6_CRTC_VERTICAL_TOTAL, gtf.getVSyncEnd() + 2); // XXX
// not
// sure,
// use
// framelength?!
vgaIO.setCRT(CR10_CRTC_VERTICAL_SYNC_START, gtf.getVSyncStart());
vgaIO.setCRT(CR11_CRTC_VERTICAL_SYNC_END, gtf.getVSyncEnd()
- gtf.getVSyncStart()); // XXX check
vgaIO.setCRT(CR12_CRTC_VERTICAL_DISPLAY_END, height - 1); // only
// least-significant
// eight
// bits are
// used! ->
// CR7 for
// bit 8 and
// 9
vgaIO.setCRT(CR15_CRTC_VERTICAL_BLANKING_START, gtf.getVSyncStart());
// TODO: handle overflow and handle shifts over than 1
if (bpp == 24)
vgaIO.setCRT(CR13_CRTC_OFFSET, 3 * width / 2 / 8);
else
vgaIO.setCRT(CR13_CRTC_OFFSET, 0x50); // TEST
vgaIO.setCRT(CR7_CRTC_OVERFLOW, (gtf.getVSyncStart() >> 2) & 0x80 | // Bit7:
// VerticalRetraceStart[9],
// extends
// CR10
((height - 1) >> 3) & 0x40 | // Bit6: VerticalDisplayEnd[9],
// extends CR12
((gtf.getVSyncEnd() + 2) >> 4) & 0x20 | // Bit5:
// VerticalTotal[9],
// extends CR6
(1 << 4) | // Bit4: LineCompare[8], XXX no idea, allways 1 for
// the moment
(gtf.getVSyncStart() >> 5) & 0x8 | // Bit3:
// VerticalBlankingStart[8],
// extends CR15
(gtf.getVSyncStart() >> 6) & 0x4 | // Bit2:
// VerticalRetraceStart[8],
// extends CR10
((height - 1) >> 7) & 0x2 | // Bit1: VerticalDisplayEnd[8],
// extends CR12
((gtf.getVSyncEnd() + 2) >> 8) & 0x1 // Bit0:
// VerticalTotal[8],
// extends CR6
);
// We use no offset for the moment. This might be used for hardware
// double buffering...
vgaIO.setCRT(CRC_START_ADDRESS_HIGH, 0);
vgaIO.setCRT(CRD_START_ADDRESS_LOW, 0);
vgaIO.setCRT(CR0_CRTC_HORIZONTAL_TOTAL, gtf.getHSyncEnd() / 8 + 5); // XXX
// not
// sure,
// use
// framelength?!
vgaIO.setCRT(CR1_CRTC_HORIZONTAL_DISPLAY_END, width / 8 - 1);
vgaIO.setCRT(CR2_CRTC_HORIZONTAL_BLANKING_START,
gtf.getHSyncStart() / 8 - 1); // XXX not sure
vgaIO.setCRT(CR3_CRTC_HORIZONTAL_BLANKING_END,
gtf.getHSyncEnd() / 8 + 1); // XXX not sure
vgaIO.setCRT(CR4_CRTC_HORIZONTAL_SYNC_START, gtf.getHSyncStart() / 8);
vgaIO.setCRT(CR5_CRTC_HORIZONTAL_SYNC_END, gtf.getHSyncEnd() / 8);
// enable writeprotection of CRT registers
vgaIO.setCRT(CR13_CRTC_OFFSET, 0x80 | vgaIO.getCRT(CR13_CRTC_OFFSET));
vgaState.dump();