150 lines
2.2 KiB
C
150 lines
2.2 KiB
C
#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 void
|
|
ct65545page(VGAscr*, int page)
|
|
{
|
|
outb(0x3D6, 0x10);
|
|
outb(0x3D7, page<<6);
|
|
}
|
|
|
|
static void
|
|
ct65545disable(VGAscr*)
|
|
{
|
|
outl(0xA3D0, 0);
|
|
}
|
|
|
|
static void
|
|
ct65545enable(VGAscr* scr)
|
|
{
|
|
ulong storage;
|
|
|
|
/*
|
|
* Find a place for the cursor data in display memory.
|
|
* Must be on a 1024-byte boundary.
|
|
*/
|
|
storage = ROUND(scr->gscreen->width*sizeof(ulong)*scr->gscreen->r.max.y, 1024);
|
|
outl(0xB3D0, storage);
|
|
scr->storage = storage;
|
|
|
|
/*
|
|
* Set the colours.
|
|
* Enable the cursor.
|
|
*/
|
|
outl(0xA7D0, 0xFFFF0000);
|
|
outl(0xA3D0, 2);
|
|
}
|
|
|
|
static void
|
|
ct65545initcursor(VGAscr* scr, int xo, int yo, int index)
|
|
{
|
|
uchar *mem;
|
|
uint and, clr, set, xor;
|
|
int i, x, y;
|
|
|
|
mem = scr->vaddr;
|
|
mem += scr->storage + index*1024;
|
|
|
|
for(y = yo; y < 16; y++){
|
|
clr = (scr->clr[2*y]<<8)|scr->clr[2*y+1];
|
|
set = (scr->set[2*y]<<8)|scr->set[2*y+1];
|
|
if(xo){
|
|
clr <<= xo;
|
|
set <<= xo;
|
|
}
|
|
|
|
and = 0;
|
|
xor = 0;
|
|
for(i = 0; i < 16; i++){
|
|
if(set & (1<<i)){
|
|
/* nothing to do */
|
|
}
|
|
else if(clr & (1<<i))
|
|
xor |= 1<<i;
|
|
else
|
|
and |= 1<<i;
|
|
}
|
|
*mem++ = and>>8;
|
|
*mem++ = xor>>8;
|
|
*mem++ = and;
|
|
*mem++ = xor;
|
|
|
|
for(x = 16; x < 64; x += 8){
|
|
*mem++ = 0xFF;
|
|
*mem++ = 0x00;
|
|
}
|
|
}
|
|
while(y < 64+yo){
|
|
for(x = 0; x < 64; x += 8){
|
|
*mem++ = 0xFF;
|
|
*mem++ = 0x00;
|
|
}
|
|
y++;
|
|
}
|
|
}
|
|
|
|
static void
|
|
ct65545load(VGAscr* scr, Cursor* curs)
|
|
{
|
|
memmove(&scr->Cursor, curs, sizeof(Cursor));
|
|
ct65545initcursor(scr, 0, 0, 0);
|
|
}
|
|
|
|
static int
|
|
ct65545move(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){
|
|
ct65545initcursor(scr, xo, yo, 1);
|
|
index = 1;
|
|
}
|
|
outl(0xB3D0, scr->storage + index*1024);
|
|
|
|
outl(0xAFD0, (y<<16)|x);
|
|
|
|
return 0;
|
|
}
|
|
|
|
VGAdev vgact65545dev = {
|
|
"ct65540", /* BUG: really 65545 */
|
|
|
|
0,
|
|
0,
|
|
ct65545page,
|
|
0,
|
|
};
|
|
|
|
VGAcur vgact65545cur = {
|
|
"ct65545hwgc",
|
|
|
|
ct65545enable,
|
|
ct65545disable,
|
|
ct65545load,
|
|
ct65545move,
|
|
};
|