/* SCROLL.C scrolling function module.
Copyright (c) 1995 Lin Ke-Fong, Ethereal Software.
*/
#include <conio.h>
#include "mpvga.h"
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
void MPVGA_SetVStart (int Sx, int Sy)
{
long int l;
int shft, x;
long int *Ptr;
shft = 5;
l = ((320 * Sy) + Sx) << 6;
switch (MPVGA_ChipType) {
case __Acer : modinx(CRTC,0x81,0x30,l >> 20); break;
case __Ahead : {
if ((rdinx(GRC,0x0C) & 0x20) > 0) l >>= 1;
modinx(GRC,0x1C,3,l >> 24);
break;
}
case __ALG : {
if ((rdinx(GRC,0x0C) & 0x10) != 0) l >>= 1;
modinx(CRTC,0x20,7,l >> 24);
break;
}
case __Alliance : modinx(CRTC,0x1C,0x0F,l >> 24); break;
case __ARK : {
if ((rdinx(CRTC,0x46) & 4) > 0) l >>= 1;
modinx(CRTC,0x40,7,l >> 24);
break;
}
case __ATI : {
if ((MPVGA_ChipVer == ATI_18800_1) && ((rdinx(IOAdr,0xB3) & 0x40) > 0) ||
(MPVGA_ChipVer >= ATI_18800_1) && ((rdinx(IOAdr,0xB0) & 0x20) > 0))
l >>= 1;
modinx(IOAdr,0xB0,0x40,l >> 18);
if (MPVGA_ChipVer > ATI_18800_1) modinx(IOAdr,0xA3,0x10,l >> 21);
if (MPVGA_ChipVer >= ATI_GUP_3) modinx(IOAdr,0xAD,0x0C,l >> 24);
break;
}
case __Chips : {
modinx(IOAdr,0x0C,7,l >> 24);
if ((rdinx(IOAdr,0x28) & 0x10) > 0) shft = 6;
break;
}
case __Cirrus54 : {
l = l + (l & 0x6000000);
modinx(CRTC,0x1B,0x0D,l >> 24);
if ((rdinx(SEQ,7) & 1) > 0) shft += 1;
if ((rdinx(SEQ,7) & 6) == 6) shft += 1;
break;
}
case __Cirrus64 : wrinx(GRC,0x7C,l >> 24); break;
case __Compaq : modinx(GRC,0x42,0x1C,l >> 22); break;
case __HMC : {
if ((rdinx(SEQ,0xE7) & 1) > 0) l >>= 1;
modinx(SEQ,0xED,1,l >> 24);
break;
}
case __Matrox : {
l >>= 1;
clrinx(CRTC,0x11,0x80);
modinx(CRTC,8,0x60,l >> 3);
modinx(0x3DE,0x0A,0x13,(l >> 24)+0x10);
break;
}
case __MXIC : modinx(SEQ,0xF1,3,l >> 24); break;
case __NCR : modinx(CRTC,0x31,0x0F,l >> 24); break;
case __Oak : {
if (MPVGA_ChipVer <= OAK_083) {
modinx(0x3DE,0x14,8,l >> 21);
modinx(0x3DE,0x16,8,l >> 22);
} else {
if ((rdinx(0x3DE,0x21) & 4) > 0) l >>= 1;
modinx(0x3DE,0x17,7,l >> 24);
}
break;
}
case __Primus : {
modinx(GRC,0x21,7,l >> 24);
shft += 1;
break;
}
case __Realtek : {
if ((rdinx(GRC,0x0C) & 0x10) != 0) l >>= 1;
l = l + (l & 0x2000000);
modinx(CRTC,0x19,0x50,l >> 20);
break;
}
case __S3 : {
wrinx(CRTC,0x38,0x48);
modinx(CRTC,0x31,0x30,l >> 20);
if (MPVGA_ChipVer > S3_924) {
wrinx(CRTC,0x39,0xA5);
modinx(CRTC,0x51,3,l >> 26);
wrinx(CRTC,0x39,0x5A);
}
wrinx(CRTC,0x38,0);
break;
}
case __Sierra : modinx(CRTC,0x1E,0x0F,l >> 24); break;
case __SiS : modinx(SEQ,0x27,0x0F,l >> 24); break;
case __Trident : {
wrinx(SEQ,0x0B,0);
if ((rdinx(SEQ,0x0D) & 0x10) > 0) l >>= 1;
if (MPVGA_ChipVer == TR_8900B || MPVGA_ChipVer == TR_8900C)
modinx(SEQ,0x0E,1,l >> 25);
rdinx(SEQ,0x0B);
modinx(CRTC,0x1E,0x20,l >> 19);
if (MPVGA_ChipVer >= TR_9000C) modinx(CRTC,0x27,3,l >> 25);
if (MPVGA_ChipVer >= TR_8900CL && (rdinx(GRC,0x0F) & 2) > 0) shft = 6;
break;
}
case __Tseng : {
if (MPVGA_ChipVer == ET_3000) {
l >>= 1;
shft += 1;
modinx(CRTC,0x23,2,l >> 23);
} else {
if (MPVGA_ChipVer == ET_4000) x = 3; else x = 0x0F;
modinx(CRTC,0x33,x,l >> 24);
}
break;
}
case __UMC : {
if ((rdinx(CRTC,0x33) & 0x10) > 0) l >>= 1;
modinx(CRTC,0x33,3,l >> 24);
break;
}
case __Video7 : {
modinx(SEQ,0xF6,0x30,l >> 20);
if ((rdinx(SEQ,0xC8) & 0x10) > 0) shft = 6;
break;
}
case __WD : {
modinx(GRC,0x0D,0x18,l >> 21);
if (MPVGA_ChipVer == WD_90c33) {
x = rdinx(CRTC,0x11);
clrinx(CRTC,0x11,0x80);
modinx(CRTC,0x3E,0x40,l >> 20);
wrinx(CRTC,0x11,x);
}
break;
}
default : return;
}
clrinx(CRTC,0x11,0x80);
wrinx(0x3C0,0x13,(l & 0xFF) >> shft);
outp(0x3C0,0x33);
wrinx(CRTC,0x0D,(l >> 8) & 0xFF);
wrinx(CRTC,0x0C,(l >> 16) & 0xFF);
return;
}