#include <string.h>
#include "chandle.h"
struct { char *dname;
int dtype;
} static dcat[]= { { "COM", 1 },{ "AUX", 1 },
{ "CON", 3 },{ "LPT", 5 },
{ "PRN", 5 },{ 0, 0 } };
static int getcat( const char *dname ) {
for( int i = 0; dcat[i].dname; i++ )
if( strnicmp( dcat[i].dname, dname, 3 ) == 0 )
break;
return dcat[i].dtype;
}
charHandle::charHandle( const char *device )
: IoctlHandle( device ) {
_cat = getcat( device );
}
charHandle *charHandle::Init(const char *device) {
charHandle *obj = new charHandle( device );
if( obj->_handle == -1 || //bad handle
obj->isFile() || //can't be a file
obj->_cat == 0 ) { //unknown device
delete obj;
return (charHandle *) 0;
}
return obj;
}
void charHandle::handle_info( int handle,
unsigned info ) {
/* Set device information word */
_iregs.x.dx = info & 0x00ff; //dh must be 0
_iregs.x.bx = handle;
int21_44h(set_handle_info);
}
unsigned charHandle::ioctl_data( ioctl_cmd fn,
unsigned count,
void *buffer ) {
/* Send/receive I/O Control data to char device */
_iregs.x.bx = _handle;
_iregs.x.cx = count; //#bytes to read/write
_iregs.x.dx = FP_OFF( (void far *) buffer );
_sregs.ds = FP_SEG( (void far *) buffer );
int21_44h(fn); //function number (2/3)
return _oregs.x.ax; //#bytes xfered
}
int charHandle::char_ioctl( char_cmd minor_code,
void *param_block ) {
/* Access DOS int21h/44h/0Ch for the current
* handle and device category, generic ioctl for
* character devices.
*/
_iregs.x.bx = _handle;
_iregs.h.ch = (char) _cat;
_iregs.h.cl = (char) minor_code;
_iregs.x.dx = FP_OFF( (void far *) param_block );
_sregs.ds = FP_SEG( (void far *) param_block );
int21_44h( gen_ioctl_char );
return_dos_error ? _oregs.x.ax: 0;
}
int charHandle::sendIoctl( unsigned *count,
void *data ) {
/* Send ioctl data to current device. */
*count = ioctl_data( send_ioctl_char,
*count, data );
return _dos_error ? _oregs.x.ax : 0;
}
int charHandle::readIoctl( unsigned *count,
void *data ) {
*count = ioctl_data( read_ioctl_char,
*count, data );
return _dos_error ? _oregs.x.ax : 0;
}
unsigned charHandle::busyCount( void ) {
/* Return LPTx device busy count, 0 on error. */
unsigned count_buf;
if( _cat != 5 ) return 0; //error
char_itoctl ( get_iter count, (void *) &count_buf );
return _dos_error ? 0 : count_buf;
}
unsigned charHandle::busyCount( unsigned count ) {
/* Set LPTx device busy count. Return new count,
* or 0 on error........ */
if( _cat != 5 ) return 0; //error
char_ioctl( set_iter_count, (void *) &count);
return busyCount();
}
int charHandle::getANSIdata( struct ANSIdata *dis) {
/* Get config data for an ANSI display driver. */
if( _cat != 3 ) return -1; //error
dis->info = 0;
dis->block_length = 14;
char_ioctl( get_display_mode, (void *) dis);
return _dos_error ? -1 : 0;
}
int charHandle::setANSIdata( struct ANSidata *dis) {
/* Set config data for an ANSI display driver. */
if( _cat != 3 ) return -1; //error
dis->info = 0;
dis->block_length = 14;
char_ioctl( set_display_mode, (void *) dis);
return _dos_error ? -1 : 0;
}
// End of File