//st4110 Copyright (C) 1989-2004 I.Pedley (CTPP) Wed 16-Feb-2000 at 21:23:44
//driver for Fujistu Stylistic ST4110
//a special case because so far, after device reset
//(which returns PnP info at 1200 baud)
//I am unable to get the device to work
//however, it is active at boot time, so by placing this driver
//in the COM drvtbl, I can detect the digitiser and install it
//before comdrv1
//note that this DRV is AFTER comdrv0 and comdrv1, because the
//DRV table is searched backwards for a match (to allow installable
//DRVs to override the inbuilt DRVs)
#pragma breakpoints on
#include {time.htm}
#include {conio.htm}
#include {string.htm}
#include {pci.htm}
#include {dev.htm}
#include {com.htm}
#include {stdlib.htm}
#include {gl.htm}
#include {msg.htm}
#include {accdis.htm}
#include {svga.htm}
#include {vesa.htm}
#include {vga.htm}
SL detectCOMport(DEV* d);
VD setCOMbaud(DEV* d,UL baudrate);
SL st4110svc(DEV* d,UL service)
{
//16550 UART services
UL port=d->iores->start;
UL n,c,p,q;
switch(service)
{//Mandatory message support//////////////////
case DM_IDENT:
n=0;
if(detectCOMport(d)){return 1;}
port=d->sv0;
outp(port+2,0x81); //attempt to set fifo on, threshold 8 bytes
if((inp(port+2)&0xc0)!=0xc0){return 1;} //its not a 16550 UART
UL baud=getCOMbaud(port);
if((baud==BAUD19200)&&(port==0x220)){return 0;}
return 1;
case DM_HANDLER:
switch(d->svtrg&0x0f)
{
case 0x01:inp(port);
n=d->svtrg;break;
case 0x06://overrun,parity,frame error or break
if(inp(port+5)&2){outp(port+2,0);outp(port+2,0x81);}
break;
case 0x0c:
case 0x04:
UL fifo=0;
do {
c=d->sv0=inp(port);
writebuf(d,(UC*)&c,1);
//downline hardware interrupt signal mechanism
if(d->skt&&d->skt->drv)
{
d->skt->svtrg=d->svtrg;
d->skt->sv0 =d->sv0;
(*d->skt->drv->svc)(d->skt,DM_CHILDHANDLER);
d->skt->svctr++;
}
// if(++fifo==16){break;}
}
while(inp(port+5)&1);
break;
case 2:
n=d->svtrg;
break;
}
// catdisp(46,40,"Com svtrg=%04X %8l ",&d->svtrg,&d->svctr);
// *(UL*)0xfec00040=0x24;
// *(UL*)0xfee000b0=0x24;
return 0;
case DM_TRIGGER:
q=inp(port+2)&0x0f;
p=inp(port+6);
return (p<<8)+q;
case DM_PREINIT: //setups before interrupts are running
return 0;
case DM_INIT:
initbuf(d,256,1);
//ST4110 digitiser is ready at boot-time but interrupts are off
outp(port+1,1); //interrupts on
DEV* sub=initdev(dpCOM,dtST4110,0,d,0,0);
if(sub)
{
PTR* p=(PTR*)sub->usr;
p->flags|=mfDIG;
p->t=p->l=0;
p->b=3995;p->r=5310;
}
return 0;
case DM_TERM:
//do nothing or ST4110 digitiser goes to sleep
termbuf(d);
case DM_RESET:
case DM_HALT:
case DM_RESUME:
return 0;
case DM_CLIDISPINFO:
CH* str=getbaudstr(d);
clidisplay("Baud rate for %sc1400 is %sc1400",d->name,str);
if(d->usr)
{
clidisplay("PnP buffer, length %4l bytes:",d->usr);
UL n,m=*(UL*)d->usr;
for(n=0;nusr+4+n*16,d->usr+4+n*16);}
}
return 0;
//device-specific section//////////////////
case DM_GETBAUDRATE:
return getCOMbaud(port);
case DM_SETBAUDRATE:
setCOMbaud(d,d->sv0);return 0;
return 0;
}
}
VD st4110rawdecode(DEV* d,PTR* p)
{
//decode raw device stream into CURSOR->status,CURSOR->dx,CURSOR->dy
//Fujitsu Stylistic 5-byte encoding is:
//
// bits: 7 6 5 4 3 2 1 0
//byte0 1 0 proximity 0 0 0 right left
// flag btn btn
//byte1 and 2 16-bit X co-ord msb, lsb
//byte3 and 4 16-bit y co-ord msb, lsb
SL st=d->buf[0];
// SL dx=*(UI*)&d->buf[1];
// SL dy=*(UI*)&d->buf[3];
SL dx=((SL)(d->buf[1])<<7)+d->buf[2];
SL dy=((SL)(d->buf[3])<<7)+d->buf[4];
//swap dx,dy using p->dx,p->dy as placeholders
if(p->flags&mfSWXY)
{p->dx=dy;p->dy=dx;}
else{p->dx=dx;p->dy=dy;}
//set mouse button status flags
if(p->flags&mfSWLR)
{
if(st&0x01){p->status|=msRIGHT;}
else {p->status&=~msRIGHT;}
if(st&0x02){p->status|=msLEFT;}
else {p->status&=~msLEFT;}
}
else
{
if(st&0x02){p->status|=msRIGHT;}
else {p->status&=~msRIGHT;}
if(st&0x01){p->status|=msLEFT;}
else {p->status&=~msLEFT;}
}
}
VD mouseevent(DEV* d,DEV* vga,PTR* p);
DEV* findbootmonitor(VD);
SL st4110digsvc(DEV* d,UL service)
{
//Fujitsu Stylistic digitiser
DEV* scr=NULL;
DISP* disp=NULL;
PTR* ptr=(PTR*)d->usr;
if(ptr)
{
scr=ptr->s;
if(scr)
{
disp=(DISP*)scr->usr;
}
}
switch(service)
{//Mandatory message support//////////////////
case DM_IDENT:
return 0; //COM DEV decides is this device is present
case DM_PREINIT:
return 0; //device MUST support DM_PREINIT
case DM_INIT:
initbuf(d,5,1);
d->usr=(PTR*)calloc(sizeof(PTR),1);
if(d->usr)
{
ptr=(PTR*)d->usr;
ptr->xdir=ptr->ydir=1;//ptr->ydir=-1;
ptr->xratio=ptr->yratio=1;
d->sv0=(UL)finddevice("cga");
(*d->drv->svc)(d,DM_SETDISPLAY);
ptr->vga=findbootmonitor();
}
return 0;
case DM_SETDISPLAY:
return 0;
case DM_TERM:
free(d->usr);
termbuf(d);
return 0;
case DM_CHILDHANDLER:
if(!d->bufin) //resynch, if ! inbyte&0x80 on byte 0 of the five
{
if(d->sv0&0x80){writebuf(d,(UC*)&d->sv0,1);}
else return 0;
}
else {writebuf(d,(UC*)&d->sv0,1);} //wraps bufin to 0 after 5 bytes
if(!d->bufin)
{//we have a sequence of five bytes in the buffer now
// clidisplay("%5H",d->buf);
if(ptr)
{
st4110rawdecode (d,ptr);
mouseevent (d,ptr->vga,ptr);
// catdisp(48,40,"st=%02X,x=%5l,y=%5l",&disp->c.status,&disp->c.posx,&disp->c.posy);
// catdisp(48,20,"st=%02X,x=%5i,y=%5i sx=%5l,sy=%5l",&disp->c.status,d->buf+1,d->buf+3,&disp->c.posx,&disp->c.posy);
SL dx=((SL)(d->buf[2])<<7)+d->buf[1];
SL dy=((SL)(d->buf[4])<<7)+d->buf[3];
// catdisp(48,20,"st=%02X,x=%5l,y=%5l sx=%5l,sy=%5l",&disp->c.status,&dx,&dy,&disp->c.posx,&disp->c.posy);
}
}
return 0;
case DM_CLIDISPINFO:
return 0;
}
}