2011-03-30 12:46:40 +00:00
|
|
|
#include "u.h"
|
|
|
|
#include "../port/lib.h"
|
|
|
|
#include "mem.h"
|
|
|
|
#include "dat.h"
|
|
|
|
#include "fns.h"
|
|
|
|
#include "io.h"
|
|
|
|
#include "../port/error.h"
|
|
|
|
|
|
|
|
#define Image IMAGE
|
|
|
|
#include <draw.h>
|
|
|
|
#include <memdraw.h>
|
|
|
|
#include <cursor.h>
|
|
|
|
#include "screen.h"
|
|
|
|
|
|
|
|
static int
|
|
|
|
clgd542xpageset(VGAscr*, int page)
|
|
|
|
{
|
|
|
|
uchar gr09;
|
|
|
|
int opage;
|
|
|
|
|
|
|
|
if(vgaxi(Seqx, 0x07) & 0xF0)
|
|
|
|
page = 0;
|
|
|
|
gr09 = vgaxi(Grx, 0x09);
|
|
|
|
if(vgaxi(Grx, 0x0B) & 0x20){
|
|
|
|
vgaxo(Grx, 0x09, page<<2);
|
|
|
|
opage = gr09>>2;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
vgaxo(Grx, 0x09, page<<4);
|
|
|
|
opage = gr09>>4;
|
|
|
|
}
|
|
|
|
|
|
|
|
return opage;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clgd542xpage(VGAscr* scr, int page)
|
|
|
|
{
|
|
|
|
lock(&scr->devlock);
|
|
|
|
clgd542xpageset(scr, page);
|
|
|
|
unlock(&scr->devlock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clgd542xlinear(VGAscr* scr, int, int)
|
|
|
|
{
|
2013-01-02 00:19:51 +00:00
|
|
|
vgalinearpci(scr);
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clgd542xdisable(VGAscr*)
|
|
|
|
{
|
|
|
|
uchar sr12;
|
|
|
|
|
|
|
|
sr12 = vgaxi(Seqx, 0x12);
|
|
|
|
vgaxo(Seqx, 0x12, sr12 & ~0x01);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clgd542xenable(VGAscr* scr)
|
|
|
|
{
|
|
|
|
uchar sr12;
|
|
|
|
int mem, x;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Disable the cursor.
|
|
|
|
*/
|
|
|
|
sr12 = vgaxi(Seqx, 0x12);
|
|
|
|
vgaxo(Seqx, 0x12, sr12 & ~0x01);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Cursor colours.
|
|
|
|
* Can't call setcolor here as cursor is already locked.
|
|
|
|
*/
|
|
|
|
vgaxo(Seqx, 0x12, sr12|0x02);
|
|
|
|
vgao(PaddrW, 0x00);
|
|
|
|
vgao(Pdata, Pwhite);
|
|
|
|
vgao(Pdata, Pwhite);
|
|
|
|
vgao(Pdata, Pwhite);
|
|
|
|
vgao(PaddrW, 0x0F);
|
|
|
|
vgao(Pdata, Pblack);
|
|
|
|
vgao(Pdata, Pblack);
|
|
|
|
vgao(Pdata, Pblack);
|
|
|
|
vgaxo(Seqx, 0x12, sr12);
|
|
|
|
|
|
|
|
mem = 0;
|
|
|
|
switch(vgaxi(Crtx, 0x27) & ~0x03){
|
|
|
|
|
|
|
|
case 0x88: /* CL-GD5420 */
|
|
|
|
case 0x8C: /* CL-GD5422 */
|
|
|
|
case 0x94: /* CL-GD5424 */
|
|
|
|
case 0x80: /* CL-GD5425 */
|
|
|
|
case 0x90: /* CL-GD5426 */
|
|
|
|
case 0x98: /* CL-GD5427 */
|
|
|
|
case 0x9C: /* CL-GD5429 */
|
|
|
|
/*
|
|
|
|
* The BIOS leaves the memory size in Seq0A, bits 4 and 3.
|
|
|
|
* See Technical Reference Manual Appendix E1, Section 1.3.2.
|
|
|
|
*
|
|
|
|
* The storage area for the 64x64 cursors is the last 16Kb of
|
|
|
|
* display memory.
|
|
|
|
*/
|
|
|
|
mem = (vgaxi(Seqx, 0x0A)>>3) & 0x03;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xA0: /* CL-GD5430 */
|
|
|
|
case 0xA8: /* CL-GD5434 */
|
|
|
|
case 0xAC: /* CL-GD5436 */
|
|
|
|
case 0xB8: /* CL-GD5446 */
|
|
|
|
case 0x30: /* CL-GD7543 */
|
|
|
|
/*
|
|
|
|
* Attempt to intuit the memory size from the DRAM control
|
|
|
|
* register. Minimum is 512KB.
|
|
|
|
* If DRAM bank switching is on then there's double.
|
|
|
|
*/
|
|
|
|
x = vgaxi(Seqx, 0x0F);
|
|
|
|
mem = (x>>3) & 0x03;
|
|
|
|
if(x & 0x80)
|
|
|
|
mem++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xBC: /* CL-GD5480 */
|
|
|
|
mem = 2; /* 1024 = 256<<2 */
|
|
|
|
x = vgaxi(Seqx, 0x0F);
|
|
|
|
if((x & 0x18) == 0x18){
|
|
|
|
mem <<= 1; /* 2048 = 256<<3 */
|
|
|
|
if(x & 0x80)
|
|
|
|
mem <<= 2; /* 2048 = 256<<4 */
|
|
|
|
}
|
|
|
|
if(vgaxi(Seqx, 0x17) & 0x80)
|
|
|
|
mem <<= 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: /* uh, ah dunno */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
scr->storage = ((256<<mem)-16)*1024;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the current cursor to index 0
|
|
|
|
* and turn the 64x64 cursor on.
|
|
|
|
*/
|
|
|
|
vgaxo(Seqx, 0x13, 0);
|
|
|
|
vgaxo(Seqx, 0x12, sr12|0x05);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clgd542xinitcursor(VGAscr* scr, int xo, int yo, int index)
|
|
|
|
{
|
|
|
|
uchar *p, seq07;
|
|
|
|
uint p0, p1;
|
|
|
|
int opage, x, y;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Is linear addressing turned on? This will determine
|
|
|
|
* how we access the cursor storage.
|
|
|
|
*/
|
|
|
|
seq07 = vgaxi(Seqx, 0x07);
|
|
|
|
opage = 0;
|
|
|
|
p = scr->vaddr;
|
|
|
|
if(!(seq07 & 0xF0)){
|
|
|
|
lock(&scr->devlock);
|
|
|
|
opage = clgd542xpageset(scr, scr->storage>>16);
|
|
|
|
p += (scr->storage & 0xFFFF);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
p += scr->storage;
|
|
|
|
p += index*1024;
|
|
|
|
|
|
|
|
for(y = yo; y < 16; y++){
|
|
|
|
p0 = scr->set[2*y];
|
|
|
|
p1 = scr->set[2*y+1];
|
|
|
|
if(xo){
|
|
|
|
p0 = (p0<<xo)|(p1>>(8-xo));
|
|
|
|
p1 <<= xo;
|
|
|
|
}
|
|
|
|
*p++ = p0;
|
|
|
|
*p++ = p1;
|
|
|
|
|
|
|
|
for(x = 16; x < 64; x += 8)
|
|
|
|
*p++ = 0x00;
|
|
|
|
|
|
|
|
p0 = scr->clr[2*y]|scr->set[2*y];
|
|
|
|
p1 = scr->clr[2*y+1]|scr->set[2*y+1];
|
|
|
|
if(xo){
|
|
|
|
p0 = (p0<<xo)|(p1>>(8-xo));
|
|
|
|
p1 <<= xo;
|
|
|
|
}
|
|
|
|
*p++ = p0;
|
|
|
|
*p++ = p1;
|
|
|
|
|
|
|
|
for(x = 16; x < 64; x += 8)
|
|
|
|
*p++ = 0x00;
|
|
|
|
}
|
|
|
|
while(y < 64+yo){
|
|
|
|
for(x = 0; x < 64; x += 8){
|
|
|
|
*p++ = 0x00;
|
|
|
|
*p++ = 0x00;
|
|
|
|
}
|
|
|
|
y++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!(seq07 & 0xF0)){
|
|
|
|
clgd542xpageset(scr, opage);
|
|
|
|
unlock(&scr->devlock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clgd542xload(VGAscr* scr, Cursor* curs)
|
|
|
|
{
|
|
|
|
uchar sr12;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Disable the cursor.
|
|
|
|
*/
|
|
|
|
sr12 = vgaxi(Seqx, 0x12);
|
|
|
|
vgaxo(Seqx, 0x12, sr12 & ~0x01);
|
|
|
|
|
|
|
|
memmove(&scr->Cursor, curs, sizeof(Cursor));
|
|
|
|
clgd542xinitcursor(scr, 0, 0, 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Enable the cursor.
|
|
|
|
*/
|
|
|
|
vgaxo(Seqx, 0x13, 0);
|
|
|
|
vgaxo(Seqx, 0x12, sr12|0x05);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
clgd542xmove(VGAscr* scr, Point p)
|
|
|
|
{
|
|
|
|
int index, x, xo, y, yo;
|
|
|
|
|
|
|
|
index = 0;
|
|
|
|
if((x = p.x+scr->offset.x) < 0){
|
|
|
|
xo = -x;
|
|
|
|
x = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
xo = 0;
|
|
|
|
if((y = p.y+scr->offset.y) < 0){
|
|
|
|
yo = -y;
|
|
|
|
y = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
yo = 0;
|
|
|
|
|
|
|
|
if(xo || yo){
|
|
|
|
clgd542xinitcursor(scr, xo, yo, 1);
|
|
|
|
index = 1;
|
|
|
|
}
|
|
|
|
vgaxo(Seqx, 0x13, index<<2);
|
|
|
|
|
|
|
|
vgaxo(Seqx, 0x10|((x & 0x07)<<5), (x>>3) & 0xFF);
|
|
|
|
vgaxo(Seqx, 0x11|((y & 0x07)<<5), (y>>3) & 0xFF);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
VGAdev vgaclgd542xdev = {
|
|
|
|
"clgd542x",
|
|
|
|
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
clgd542xpage,
|
|
|
|
clgd542xlinear,
|
|
|
|
};
|
|
|
|
|
|
|
|
VGAcur vgaclgd542xcur = {
|
|
|
|
"clgd542xhwgc",
|
|
|
|
|
|
|
|
clgd542xenable,
|
|
|
|
clgd542xdisable,
|
|
|
|
clgd542xload,
|
|
|
|
clgd542xmove,
|
|
|
|
};
|