#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "../port/error.h" #include <draw.h>#include <memdraw.h>#include <cursor.h> #include "screen.h" enum { Backgnd = 0xFF, /* white */ Foregnd = 0x00, /* black */}; Cursor arrow = { { -1, -1 }, { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C, 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04, 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04, 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40, }, { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0, 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8, 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8, 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00, },}; static Memdata xgdata;static Memimage xgscreen ={ {0, 0, 0, 0}, /* r */ {0, 0, 0, 0}, /* clipr */ 8, /* depth */ 1, /* nchan */ CMAP8, /* chan */ nil, /* cmap */ &xgdata, /* data */ 0, /* zero */ 0, /* width */ nil, /* layer */ 0, /* flags */}; int novgascreen; /* optionally set by configuration file */static int lcdpdpar; /* value to load into io->pdpar */ Memimage *gscreen;Memimage *conscol;Memimage *back; static Memsubfont *memdefont;static Lock palettelock; /* access to DAC registers */static Lock screenlock;static int h;static Point curpos;static Rectangle window; typedef struct SWcursor SWcursor;static SWcursor *swc = nil;SWcursor* swcurs_create(ulong *, int, int, Rectangle, int);void swcurs_destroy(SWcursor*);void swcurs_enable(SWcursor*);void swcurs_disable(SWcursor*);void swcurs_hide(SWcursor*);void swcurs_unhide(SWcursor*);void swcurs_load(SWcursor*, Cursor*); static void screenputc(char*);static void scroll(void);static void setscreen(Mode*);static void cursorlock(Rectangle);static void cursorunlock(void);static void lcdinit(Mode*);static void lcdsetrgb(int, ulong, ulong, ulong); /* * Called by main(). */voidscreeninit(void){ Mode m; novgascreen=1; return; /* default size and parameters */ memset(&m.lcd, 0, sizeof(m.lcd)); m.x = 640; m.y = 480; m.d = 3; if(novgascreen == 0 && archlcdmode(&m) >= 0){ memdefont = getmemdefont(); setscreen(&m); }} /* * On 8 bit displays, load the default color map */voidgraphicscmap(int invert){ int num, den, i, j; int r, g, b, cr, cg, cb, v; for(r=0,i=0;r!=4;r++) for(v=0;v!=4;v++,i+=16){ for(g=0,j=v-r;g!=4;g++) for(b=0;b!=4;b++,j++){ den=r; if(g>den) den=g; if(b>den) den=b; if(den==0) /* divide check -- pick grey shades */ cr=cg=cb=v*17; else{ num=17*(4*den+v); cr=r*num/den; cg=g*num/den; cb=b*num/den; } if(invert) setcolor(255-i-(j&15), cr*0x01010101, cg*0x01010101, cb*0x01010101); else setcolor(i+(j&15), cr*0x01010101, cg*0x01010101, cb*0x01010101); } }} /* * reconfigure screen shape */static voidsetscreen(Mode *mode){ int h; if(swc) swcurs_destroy(swc); gscreen = &xgscreen; xgdata.ref = 1; lcdinit(mode); xgdata.bdata = (uchar*)mode->aperture; if(xgdata.bdata == nil) panic("setscreen: vga soft memory"); gscreen->r = Rect(0, 0, mode->x, mode->y); gscreen->clipr = gscreen->r; gscreen->depth = 1<<mode->d; gscreen->width = wordsperline(gscreen->r, gscreen->depth); memimageinit(); memdefont = getmemdefont(); memsetchan(gscreen, CMAP8); back = memwhite; conscol = memblack; memimagedraw(gscreen, gscreen->r, memwhite, ZP, memopaque, ZP, SoverD); graphicscmap(0); /* get size for a system window */ h = memdefont->height; window = insetrect(gscreen->r, 4); window.max.y = window.min.y+(Dy(window)/h)*h; curpos = window.min;// screenclear(); graphicscmap(0); // swc = swcurs_create(gscreendata.data, gscreen.width, gscreen.ldepth, gscreen.r, 1); drawcursor(nil);} enum { ScreenCached = 1 /* non-zero if screen region not write-through */}; voidflushmemscreen(Rectangle r){ if(rectclip(&r, gscreen->r) == 0) return; if(r.min.x >= r.max.x || r.min.y >= r.max.y) return; if(ScreenCached) dcflush((ulong*)gscreen->data->bdata + gscreen->width*r.min.y, gscreen->width*Dy(r));} /* * export screen to interpreter */uchar*attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen){ *r = gscreen->r; *d = gscreen->depth; *chan = gscreen->chan; *width = gscreen->width; *softscreen = ScreenCached; return (uchar*)gscreen->data->bdata;} voiddetachscreen(void){} /* * write a string to the screen */voidscreenputs(char *s, int n){ int i; Rune r; char buf[4]; if(novgascreen || xgdata.bdata == nil || memdefont == nil) return; if(islo() == 0) { /* don't deadlock trying to print in interrupt */ if(!canlock(&screenlock)) return; } else lock(&screenlock); while(n > 0) { i = chartorune(&r, s); if(i == 0){ s++; --n; continue; } memmove(buf, s, i); buf[i] = 0; n -= i; s += i; screenputc(buf); } /* Only OK for now */ flushmemscreen(gscreen->r); unlock(&screenlock);} static voidscroll(void){ int o; Point p; Rectangle r; o = 4*memdefont->height; r = Rpt(window.min, Pt(window.max.x, window.max.y-o)); p = Pt(window.min.x, window.min.y+o); memimagedraw(gscreen, r, gscreen, p, nil, p, SoverD); flushmemscreen(r); r = Rpt(Pt(window.min.x, window.max.y-o), window.max); memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); flushmemscreen(r); curpos.y -= o;} static voidclearline(void){ Rectangle r; int yloc = curpos.y; r = Rpt(Pt(window.min.x, window.min.y + yloc), Pt(window.max.x, window.min.y+yloc+memdefont->height)); memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD);} static voidscreenputc(char *buf){ Point p; int h, w, pos; Rectangle r; static int *xp; static int xbuf[256]; h = memdefont->height; if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) xp = xbuf; switch(buf[0]) { case '\n': if(curpos.y+h >= window.max.y) scroll(); curpos.y += h; /* fall through */ case '\r': xp = xbuf; curpos.x = window.min.x; break; case '\t': if(curpos.x == window.min.x) clearline(); p = memsubfontwidth(memdefont, " "); w = p.x; *xp++ = curpos.x; pos = (curpos.x-window.min.x)/w; pos = 8-(pos%8); r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y+h); memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); flushmemscreen(r); curpos.x += pos*w; break; case '\b': if(xp <= xbuf) break; xp--; r = Rpt(Pt(*xp, curpos.y), Pt(curpos.x, curpos.y + h)); memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); flushmemscreen(r); curpos.x = *xp; break; case '\0': break; default: p = memsubfontwidth(memdefont, buf); w = p.x; if(curpos.x >= window.max.x-w) screenputc("\n"); if(curpos.x == window.min.x) clearline(); if(xp < xbuf+nelem(xbuf)) *xp++ = curpos.x; r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h); memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf); flushmemscreen(r); curpos.x += w; }} intsetcolor(ulong p, ulong r, ulong g, ulong b){ ulong x; if(gscreen->depth >= 8) x = 0xFF; else x = 0xF; p &= x; p ^= x; lock(&palettelock); lcdsetrgb(p, r, g, b); unlock(&palettelock); return ~0;} voidgetcolor(ulong p, ulong *pr, ulong *pg, ulong *pb){ /* TO DO */ *pr = *pg = *pb = 0;} /* * See section 5.2.1 (page 5-6) of the MPC823 manual */static uchar lcdclock[17] = { /* (a<<2)|b => divisor of (1<<a)*((b<<1)+1) */ 0, 0, (1<<2), 1, (2<<2), 2, (1<<2)|1, 3, (3<<2), (1<<2)|2, (1<<2)|2, (2<<2)|1, (2<<2)|1, (1<<2)|3, (1<<2)|3, (4<<2), (4<<2)}; enum { /* lccr */ Enable = 1<<0, /* lchcr */ BigEndian = 1<<24, AT7 = 7<<21, /* access type */ /* sdcr */ LAM = 1<<6, /* ``LCD aggressive mode'' */}; /* * initialise MPC8xx LCD controller incorporating board or display-specific values in Mode.lcd */static voidlcdinit(Mode *mode){ IMM *io; int i, d; long hz; io = m->iomem; mode->aperture = xspanalloc(mode->x*mode->y, 16, 0); mode->apsize = mode->x*mode->y; io->sdcr = 1; /* MPC823 errata: turn off LAM before disabling controller */ eieio(); io->lcfaa = PADDR(mode->aperture); io->lccr = (((mode->x*mode->y*(1<<mode->d)+127)/128) << 17) | (mode->d << 5) | mode->lcd.flags; switch(mode->d){ default: case 0: /* monochrome/greyscale identity map */ for(i=0; i<16; i++) io->lcdmap[i] = i; break; case 2: /* 4-bit grey scale map */ for(i=0; i<16; i++) io->lcdmap[0] = (i<<8)|(i<<4)|i; break; case 3: /* 8-bit linear map */ for(i=0; i<256; i++) io->lcdmap[i] = (i<<8)|(i<<4)|i; break; } io->lcvcr = (mode->y << 11) | (mode->lcd.vpw<<28) | (mode->lcd.ac<<21) | mode->lcd.wbf; io->lchcr = (mode->x<<10) | BigEndian | mode->lcd.wbl; hz = m->cpuhz; d = hz/mode->lcd.freq; if(hz/d > mode->lcd.freq) d++; if(d >= 16) d = 16; /* * enable LCD outputs */ io->pddat = 0; lcdpdpar = 0x1fff & ~mode->lcd.notpdpar; io->pdpar = lcdpdpar; io->pddir = 0x1fff; io->pbpar |= IBIT(31) | IBIT(19) | IBIT(17); io->pbdir |= IBIT(31) | IBIT(19) | IBIT(17); io->pbodr &= ~(IBIT(31) | IBIT(19) | IBIT(17)); /* * with the data cache off, early revisions of the 823 did not require * the `aggressive' DMA priority to avoid flicker, but flicker is obvious * on the 823A when the cache is on, so LAM is now set */ io->sdcr = (io->sdcr & ~0xF) | LAM; /* LAM=1, LAID=0, RAID=0 */ // gscreen.width = gscreen.width; /* access external memory before enabling (mpc823 errata) */ eieio(); io->sccrk = KEEP_ALIVE_KEY; eieio(); io->sccr = (io->sccr & ~0x1F) | lcdclock[d]; eieio(); io->sccrk= ~KEEP_ALIVE_KEY; io->lcsr = 7; /* clear status */ eieio(); io->lccr |= Enable; archbacklight(1);} static voidlcdsetrgb(int p, ulong r, ulong g, ulong b){ r >>= 28; g >>= 28; b >>= 28; m->iomem->lcdmap[p&0xFF] = (r<<8) | (g<<4) | b;} voidblankscreen(int blank){ USED(blank); /* TO DO */} /* * enable/disable LCD panel (eg, when using video subsystem) */voidlcdpanel(int on){ IMM *io; if(on){ archbacklight(1); io = ioplock(); io->pddat = 0;Lines 1–500 of 832. Load more
#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "../port/error.h" #include <draw.h> #include <memdraw.h> #include <cursor.h> #include "screen.h" enum { Backgnd = 0xFF, /* white */ Foregnd = 0x00, /* black */ }; Cursor arrow = { { -1, -1 }, { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C, 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04, 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04, 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40, }, { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0, 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8, 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8, 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00, }, }; static Memdata xgdata; static Memimage xgscreen = { {0, 0, 0, 0}, /* r */ {0, 0, 0, 0}, /* clipr */ 8, /* depth */ 1, /* nchan */ CMAP8, /* chan */ nil, /* cmap */ &xgdata, /* data */ 0, /* zero */ 0, /* width */ nil, /* layer */ 0, /* flags */ }; int novgascreen; /* optionally set by configuration file */ static int lcdpdpar; /* value to load into io->pdpar */ Memimage *gscreen; Memimage *conscol; Memimage *back; static Memsubfont *memdefont; static Lock palettelock; /* access to DAC registers */ static Lock screenlock; static int h; static Point curpos; static Rectangle window; typedef struct SWcursor SWcursor; static SWcursor *swc = nil; SWcursor* swcurs_create(ulong *, int, int, Rectangle, int); void swcurs_destroy(SWcursor*); void swcurs_enable(SWcursor*); void swcurs_disable(SWcursor*); void swcurs_hide(SWcursor*); void swcurs_unhide(SWcursor*); void swcurs_load(SWcursor*, Cursor*); static void screenputc(char*); static void scroll(void); static void setscreen(Mode*); static void cursorlock(Rectangle); static void cursorunlock(void); static void lcdinit(Mode*); static void lcdsetrgb(int, ulong, ulong, ulong); /* * Called by main(). */ void screeninit(void) { Mode m; novgascreen=1; return; /* default size and parameters */ memset(&m.lcd, 0, sizeof(m.lcd)); m.x = 640; m.y = 480; m.d = 3; if(novgascreen == 0 && archlcdmode(&m) >= 0){ memdefont = getmemdefont(); setscreen(&m); } } /* * On 8 bit displays, load the default color map */ void graphicscmap(int invert) { int num, den, i, j; int r, g, b, cr, cg, cb, v; for(r=0,i=0;r!=4;r++) for(v=0;v!=4;v++,i+=16){ for(g=0,j=v-r;g!=4;g++) for(b=0;b!=4;b++,j++){ den=r; if(g>den) den=g; if(b>den) den=b; if(den==0) /* divide check -- pick grey shades */ cr=cg=cb=v*17; else{ num=17*(4*den+v); cr=r*num/den; cg=g*num/den; cb=b*num/den; } if(invert) setcolor(255-i-(j&15), cr*0x01010101, cg*0x01010101, cb*0x01010101); else setcolor(i+(j&15), cr*0x01010101, cg*0x01010101, cb*0x01010101); } } } /* * reconfigure screen shape */ static void setscreen(Mode *mode) { int h; if(swc) swcurs_destroy(swc); gscreen = &xgscreen; xgdata.ref = 1; lcdinit(mode); xgdata.bdata = (uchar*)mode->aperture; if(xgdata.bdata == nil) panic("setscreen: vga soft memory"); gscreen->r = Rect(0, 0, mode->x, mode->y); gscreen->clipr = gscreen->r; gscreen->depth = 1<<mode->d; gscreen->width = wordsperline(gscreen->r, gscreen->depth); memimageinit(); memdefont = getmemdefont(); memsetchan(gscreen, CMAP8); back = memwhite; conscol = memblack; memimagedraw(gscreen, gscreen->r, memwhite, ZP, memopaque, ZP, SoverD); graphicscmap(0); /* get size for a system window */ h = memdefont->height; window = insetrect(gscreen->r, 4); window.max.y = window.min.y+(Dy(window)/h)*h; curpos = window.min; // screenclear(); graphicscmap(0); // swc = swcurs_create(gscreendata.data, gscreen.width, gscreen.ldepth, gscreen.r, 1); drawcursor(nil); } enum { ScreenCached = 1 /* non-zero if screen region not write-through */ }; void flushmemscreen(Rectangle r) { if(rectclip(&r, gscreen->r) == 0) return; if(r.min.x >= r.max.x || r.min.y >= r.max.y) return; if(ScreenCached) dcflush((ulong*)gscreen->data->bdata + gscreen->width*r.min.y, gscreen->width*Dy(r)); } /* * export screen to interpreter */ uchar* attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen) { *r = gscreen->r; *d = gscreen->depth; *chan = gscreen->chan; *width = gscreen->width; *softscreen = ScreenCached; return (uchar*)gscreen->data->bdata; } void detachscreen(void) { } /* * write a string to the screen */ void screenputs(char *s, int n) { int i; Rune r; char buf[4]; if(novgascreen || xgdata.bdata == nil || memdefont == nil) return; if(islo() == 0) { /* don't deadlock trying to print in interrupt */ if(!canlock(&screenlock)) return; } else lock(&screenlock); while(n > 0) { i = chartorune(&r, s); if(i == 0){ s++; --n; continue; } memmove(buf, s, i); buf[i] = 0; n -= i; s += i; screenputc(buf); } /* Only OK for now */ flushmemscreen(gscreen->r); unlock(&screenlock); } static void scroll(void) { int o; Point p; Rectangle r; o = 4*memdefont->height; r = Rpt(window.min, Pt(window.max.x, window.max.y-o)); p = Pt(window.min.x, window.min.y+o); memimagedraw(gscreen, r, gscreen, p, nil, p, SoverD); flushmemscreen(r); r = Rpt(Pt(window.min.x, window.max.y-o), window.max); memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); flushmemscreen(r); curpos.y -= o; } static void clearline(void) { Rectangle r; int yloc = curpos.y; r = Rpt(Pt(window.min.x, window.min.y + yloc), Pt(window.max.x, window.min.y+yloc+memdefont->height)); memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); } static void screenputc(char *buf) { Point p; int h, w, pos; Rectangle r; static int *xp; static int xbuf[256]; h = memdefont->height; if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) xp = xbuf; switch(buf[0]) { case '\n': if(curpos.y+h >= window.max.y) scroll(); curpos.y += h; /* fall through */ case '\r': xp = xbuf; curpos.x = window.min.x; break; case '\t': if(curpos.x == window.min.x) clearline(); p = memsubfontwidth(memdefont, " "); w = p.x; *xp++ = curpos.x; pos = (curpos.x-window.min.x)/w; pos = 8-(pos%8); r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y+h); memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); flushmemscreen(r); curpos.x += pos*w; break; case '\b': if(xp <= xbuf) break; xp--; r = Rpt(Pt(*xp, curpos.y), Pt(curpos.x, curpos.y + h)); memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); flushmemscreen(r); curpos.x = *xp; break; case '\0': break; default: p = memsubfontwidth(memdefont, buf); w = p.x; if(curpos.x >= window.max.x-w) screenputc("\n"); if(curpos.x == window.min.x) clearline(); if(xp < xbuf+nelem(xbuf)) *xp++ = curpos.x; r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h); memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf); flushmemscreen(r); curpos.x += w; } } int setcolor(ulong p, ulong r, ulong g, ulong b) { ulong x; if(gscreen->depth >= 8) x = 0xFF; else x = 0xF; p &= x; p ^= x; lock(&palettelock); lcdsetrgb(p, r, g, b); unlock(&palettelock); return ~0; } void getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) { /* TO DO */ *pr = *pg = *pb = 0; } /* * See section 5.2.1 (page 5-6) of the MPC823 manual */ static uchar lcdclock[17] = { /* (a<<2)|b => divisor of (1<<a)*((b<<1)+1) */ 0, 0, (1<<2), 1, (2<<2), 2, (1<<2)|1, 3, (3<<2), (1<<2)|2, (1<<2)|2, (2<<2)|1, (2<<2)|1, (1<<2)|3, (1<<2)|3, (4<<2), (4<<2) }; enum { /* lccr */ Enable = 1<<0, /* lchcr */ BigEndian = 1<<24, AT7 = 7<<21, /* access type */ /* sdcr */ LAM = 1<<6, /* ``LCD aggressive mode'' */ }; /* * initialise MPC8xx LCD controller incorporating board or display-specific values in Mode.lcd */ static void lcdinit(Mode *mode) { IMM *io; int i, d; long hz; io = m->iomem; mode->aperture = xspanalloc(mode->x*mode->y, 16, 0); mode->apsize = mode->x*mode->y; io->sdcr = 1; /* MPC823 errata: turn off LAM before disabling controller */ eieio(); io->lcfaa = PADDR(mode->aperture); io->lccr = (((mode->x*mode->y*(1<<mode->d)+127)/128) << 17) | (mode->d << 5) | mode->lcd.flags; switch(mode->d){ default: case 0: /* monochrome/greyscale identity map */ for(i=0; i<16; i++) io->lcdmap[i] = i; break; case 2: /* 4-bit grey scale map */ for(i=0; i<16; i++) io->lcdmap[0] = (i<<8)|(i<<4)|i; break; case 3: /* 8-bit linear map */ for(i=0; i<256; i++) io->lcdmap[i] = (i<<8)|(i<<4)|i; break; } io->lcvcr = (mode->y << 11) | (mode->lcd.vpw<<28) | (mode->lcd.ac<<21) | mode->lcd.wbf; io->lchcr = (mode->x<<10) | BigEndian | mode->lcd.wbl; hz = m->cpuhz; d = hz/mode->lcd.freq; if(hz/d > mode->lcd.freq) d++; if(d >= 16) d = 16; /* * enable LCD outputs */ io->pddat = 0; lcdpdpar = 0x1fff & ~mode->lcd.notpdpar; io->pdpar = lcdpdpar; io->pddir = 0x1fff; io->pbpar |= IBIT(31) | IBIT(19) | IBIT(17); io->pbdir |= IBIT(31) | IBIT(19) | IBIT(17); io->pbodr &= ~(IBIT(31) | IBIT(19) | IBIT(17)); /* * with the data cache off, early revisions of the 823 did not require * the `aggressive' DMA priority to avoid flicker, but flicker is obvious * on the 823A when the cache is on, so LAM is now set */ io->sdcr = (io->sdcr & ~0xF) | LAM; /* LAM=1, LAID=0, RAID=0 */ // gscreen.width = gscreen.width; /* access external memory before enabling (mpc823 errata) */ eieio(); io->sccrk = KEEP_ALIVE_KEY; eieio(); io->sccr = (io->sccr & ~0x1F) | lcdclock[d]; eieio(); io->sccrk= ~KEEP_ALIVE_KEY; io->lcsr = 7; /* clear status */ eieio(); io->lccr |= Enable; archbacklight(1); } static void lcdsetrgb(int p, ulong r, ulong g, ulong b) { r >>= 28; g >>= 28; b >>= 28; m->iomem->lcdmap[p&0xFF] = (r<<8) | (g<<4) | b; } void blankscreen(int blank) { USED(blank); /* TO DO */ } /* * enable/disable LCD panel (eg, when using video subsystem) */ void lcdpanel(int on) { IMM *io; if(on){ archbacklight(1); io = ioplock(); io->pddat = 0;