version 1.1, 2007/10/16 09:41:04 |
version 1.5, 2008/01/11 15:36:01 |
|
|
#include <sys/device.h> |
#include <sys/device.h> |
#include <dev/fcons/fconsvar.h> |
#include <dev/fcons/fconsvar.h> |
#include <libkern/printf.h> |
#include <libkern/printf.h> |
|
#include <libkern/queue.h> |
|
|
/* |
/* |
* funnyOS console. |
* funnyOS console. |
* 80x25, monochrome. |
* 80x25, monochrome. |
*/ |
*/ |
|
|
struct fcons_devdata fcons_dd[NFCONS]; |
|
|
|
/* current console device */ |
/* current console device */ |
struct device *curcons; |
struct fcons_dd *curcons; |
|
|
extern void (*putchar)(char); |
extern void (*putchar)(char); |
|
|
int fcons_attach(struct device *); |
int fcons_attach(struct device *, uint32_t loc, uint8_t flags); |
void fcons_putchar(struct device *, char); |
void fcons_putchar(void *ddp, char); |
char fcons_getchar(struct device *); |
char fcons_getchar(void *ddp); |
void fcons_dfltputchar(char); |
void fcons_dfltputchar(char); |
int fcons_devctl(struct device *, uint8_t, void *); |
int fcons_devctl(struct device *, uint8_t, void *); |
|
|
|
struct driver fcons_dr = { |
|
sizeof(struct fcons_dd), |
|
fcons_attach, |
|
NULL, |
|
NULL |
|
}; |
|
|
int |
int |
fcons_attach(struct device *self) |
fcons_attach(struct device *self, uint32_t loc, uint8_t size) |
{ |
{ |
/* |
struct fcons_dd *ddp = self->dv_devdata; |
* Attach fcons abstraction using parent's getc & putc. |
|
*/ |
|
/* associate dev data */ |
|
self->dv_devdata = &fcons_dd[self->dv_minor]; |
|
|
|
fcons_dd[self->dv_minor].currow = 0; |
/* link our parent's dv_aux (fcons_handle) to us */ |
fcons_dd[self->dv_minor].curcol = 0; |
ddp->fd_fh = self->dv_parent->dv_aux; |
|
|
/* make cureent console default */ |
ddp->fd_currow = 0; |
curcons = self; |
ddp->fd_curcol = 0; |
|
|
/* |
/* initialize iqueue */ |
* XXX Register system printf's , etc.. |
// ddp->fd_iqhead = SIMPLEQ_HEAD_INITIALIZER(ddp->fd_iqhead); |
*/ |
SIMPLEQ_INIT(ddp->head); |
|
ddp->fd_iqlength = 0; |
|
|
|
/* make current console default */ |
|
curcons = ddp; |
|
|
/* override early putchar */ |
/* override early putchar */ |
putchar = fcons_dfltputchar; |
putchar = fcons_dfltputchar; |
|
|
|
|
|
|
|
|
void |
void |
fcons_putchar(struct device *devp, char ch) |
fcons_putchar(void *ddp, char ch) |
{ |
{ |
struct consoleops *copsp; |
struct fcons_dd *fdp = ddp; |
|
struct fcons_handle *fhp = fdp->fd_fh; |
|
|
copsp = devp->dv_parent->dv_devdata; |
/* if we reach screen width */ |
|
if (fdp->fd_curcol == (FCONS_WIDTH - 1)) { |
if (fcons_dd[devp->dv_minor].curcol == (FCONS_WIDTH - 1)) { |
|
/* CRLF */ |
/* CRLF */ |
fcons_dd[devp->dv_minor].curcol = 0; |
fdp->fd_curcol = 0; |
fcons_dd[devp->dv_minor].currow++; |
fdp->fd_currow++; |
|
|
/* XXX pass \n to lower level (not all devices work this way) */ |
/* XXX pass \n to lower level (not all devices work this way) */ |
copsp->putc(devp->dv_parent, '\n'); |
fhp->putc(fhp->fh_ownerdd, '\n'); |
} |
} |
/* XXX do something if col == FCONS_HEIGHT; console buffer? */ |
/* XXX do something if col == FCONS_HEIGHT; console buffer? */ |
|
|
if (fcons_dd[devp->dv_minor].currow == FCONS_HEIGHT) { |
/* if we reach the bottom of the screen */ |
/* tmp hack; should really follow clrscr */ |
if (fdp->fd_currow == FCONS_HEIGHT) { |
fcons_dd[devp->dv_minor].currow = 0; |
/* XXX tmp hack; should really follow clrscr */ |
|
fdp->fd_currow = 0; |
} |
} |
|
|
copsp->putc(devp->dv_parent, ch); |
fhp->putc(fhp->fh_ownerdd, ch); |
} |
} |
|
|
|
|
char |
char |
fcons_getchar(struct device *devp) |
fcons_getchar(void *ddp) |
{ |
{ |
/* TODO */ |
/* TODO */ |
return ' '; |
return ' '; |
|
|
} |
} |
|
|
|
|
|
void |
|
fcons_ienqueue(char ch) |
|
{ |
|
/* |
|
* Enqueue character into the input data queue. |
|
*/ |
|
struct fcons_dd *ddp; |
|
struct fcons_char *curfc; |
|
uint32_t i; |
|
|
|
/* XXX will use curcons devdata */ |
|
ddp = curcons; |
|
|
|
#if 0 |
|
if (ddp->fd_iqueue == NULL) { |
|
/* first insertion */ |
|
curfc = kmalloc(sizeof(struct fcons_char)); |
|
|
|
if(curfc == NULL) |
|
panic("fcons_ienqueue: can't allocate memory for new element\n"); |
|
} else { |
|
curfc = ddp->fd_iqueue; |
|
|
|
/* locate last element */ |
|
for(i = 0; i < ddp->fd_iqlength - 1; i++) |
|
curfc = curfc->fc_next; |
|
} |
|
#endif |
|
curfc = kmalloc(sizeof(struct fcons_char)); |
|
if(curfc == NULL) |
|
panic("fcons_ienqueue: can't allocate memory for new element\n"); |
|
|
|
SIMPLEQ_INSERT_TAIL(ddp->fd_iqhead, curfc, fc_next); |
|
} |
|
|
|
#if 0 |
int |
int |
fcons_devctl(struct device *devp, uint8_t ctl, void *data) |
fcons_devctl(struct device *devp, uint8_t ctl, void *data) |
{ |
{ |
|
|
} |
} |
|
|
} |
} |
|
#endif /* not 0 */ |
|
|