diff options
| author | Yoshihiro Takahashi <nyan@FreeBSD.org> | 2000-08-13 10:59:00 +0000 |
|---|---|---|
| committer | Yoshihiro Takahashi <nyan@FreeBSD.org> | 2000-08-13 10:59:00 +0000 |
| commit | 42e68916e988b25f10d566a9eff7fd82eb516474 (patch) | |
| tree | 058fea27eadf309bf7b98bfd761ac007d1e6dad0 /sys/modules | |
| parent | 1eeb928b41a128bc2e110c5ac05b2bf8ee128f94 (diff) | |
Notes
Diffstat (limited to 'sys/modules')
| -rw-r--r-- | sys/modules/splash/bmp/Makefile | 4 | ||||
| -rw-r--r-- | sys/modules/splash/bmp/splash_bmp.c | 191 |
2 files changed, 127 insertions, 68 deletions
diff --git a/sys/modules/splash/bmp/Makefile b/sys/modules/splash/bmp/Makefile index af009a282619..9c45c39c4473 100644 --- a/sys/modules/splash/bmp/Makefile +++ b/sys/modules/splash/bmp/Makefile @@ -5,4 +5,8 @@ SRCS= splash_bmp.c NOMAN= +.if ${MACHINE} == "pc98" +CFLAGS+= -DPC98 +.endif + .include <bsd.kmod.mk> diff --git a/sys/modules/splash/bmp/splash_bmp.c b/sys/modules/splash/bmp/splash_bmp.c index 71a53b9c38a4..e3db76da12a0 100644 --- a/sys/modules/splash/bmp/splash_bmp.c +++ b/sys/modules/splash/bmp/splash_bmp.c @@ -35,6 +35,11 @@ #include <dev/fb/fbreg.h> #include <dev/fb/splashreg.h> +#ifndef PC98 +#include <dev/fb/vgareg.h> + +#include <isa/isareg.h> +#endif #define FADE_TIMEOUT 15 /* sec */ #define FADE_LEVELS 10 @@ -59,14 +64,25 @@ bmp_start(video_adapter_t *adp) { /* currently only 256-color modes are supported XXX */ static int modes[] = { +#ifdef PC98 + /* + * As 640x400 doesn't generally look great, + * it's least preferred here. + */ + M_PC98_PEGC640x400, + M_PC98_PEGC640x480, + M_PC98_EGC640x400, +#else M_VESA_CG640x480, M_VESA_CG800x600, M_VESA_CG1024x768, + M_CG640x480, /* * As 320x200 doesn't generally look great, * it's least preferred here. */ M_VGA_CG320, +#endif -1, }; video_info_t info; @@ -212,6 +228,7 @@ typedef struct { int width,height; /* image dimensions */ int swidth,sheight; /* screen dimensions for the current mode */ + u_char depth; /* image depth (1, 4, 8, 24 bits) */ u_char sdepth; /* screen depth (1, 4, 8 bpp) */ int ncols; /* number of colours */ u_char palette[256][3]; /* raw palette data */ @@ -221,46 +238,13 @@ typedef struct u_char *vidmem; /* video memory allocated for drawing */ video_adapter_t *adp; int bank; +#ifdef PC98 + u_char prev_val; +#endif } BMP_INFO; static BMP_INFO bmp_info; -static void -fill(BMP_INFO *info, int x, int y, int xsize, int ysize) -{ - u_char *window; - int banksize; - int bank; - int p; - - banksize = info->adp->va_window_size; - bank = (info->adp->va_line_width*y + x)/banksize; - window = (u_char *)info->adp->va_window; - (*vidsw[info->adp->va_index]->set_win_org)(info->adp, bank*banksize); - while (ysize > 0) { - p = (info->adp->va_line_width*y + x)%banksize; - for (; (p + xsize <= banksize) && ysize > 0; --ysize, ++y) { - generic_bzero(window + p, xsize); - p += info->adp->va_line_width; - } - if (ysize <= 0) - break; - if (p < banksize) { - /* the last line crosses the window boundary */ - generic_bzero(window + p, banksize - p); - } - ++bank; /* next bank */ - (*vidsw[info->adp->va_index]->set_win_org)(info->adp, bank*banksize); - if (p < banksize) { - /* the remaining part of the last line */ - generic_bzero(window, p + xsize - banksize); - ++y; - --ysize; - } - } - info->bank = bank; -} - /* ** bmp_SetPix ** @@ -271,7 +255,6 @@ static void bmp_SetPix(BMP_INFO *info, int x, int y, u_char val) { int sofs, bofs; - u_char tpv, mask; int newbank; /* @@ -286,31 +269,48 @@ bmp_SetPix(BMP_INFO *info, int x, int y, u_char val) */ sofs = ((info->height - (y+1) + (info->sheight - info->height) / 2) * info->adp->va_line_width); + x += (info->swidth - info->width) / 2; switch(info->sdepth) { - case 1: - sofs += ((x + (info->swidth - info->width) / 2) >> 3); +#ifdef PC98 + case 4: + x += (info->swidth - info->width) / 2; + sofs += (x >> 3); bofs = x & 0x7; /* offset within byte */ - - val &= 1; /* mask pixel value */ - mask = ~(0x80 >> bofs); /* calculate bit mask */ - tpv = *(info->vidmem+sofs) & mask; /* get screen contents, excluding masked bit */ - *(info->vidmem+sofs) = tpv | (val << (8-bofs)); /* write new bit */ - break; - /* XXX only correct for non-interleaved modes */ + outb(0x7c, 0x80 | 0x40); /* GRCG on & RMW mode */ + if (val != info->prev_val) { + outb(0x7e, (val & 1) ? 0xff : 0); /* tile B */ + outb(0x7e, (val & 2) ? 0xff : 0); /* tile R */ + outb(0x7e, (val & 4) ? 0xff : 0); /* tile G */ + outb(0x7e, (val & 8) ? 0xff : 0); /* tile I */ + + info->prev_val = val; + } + + *(info->vidmem+sofs) = (0x80 >> bofs); /* write new bit */ + outb(0x7c, 0); /* GRCG off */ + break; +#else case 4: - sofs += ((x + (info->swidth - info->width) / 2) >> 1); - bofs = x & 0x1; /* offset within byte */ - - val &= 0xf; /* mask pixel value */ - mask = bofs ? 0x0f : 0xf0; /* calculate bit mask */ - tpv = *(info->vidmem+sofs) & mask; /* get screen contents, excluding masked bits */ - *(info->vidmem+sofs) = tpv | (val << (bofs ? 0 : 4)); /* write new bits */ + case 1: + /* EGA/VGA planar modes */ + sofs += (x >> 3); + newbank = sofs/info->adp->va_window_size; + if (info->bank != newbank) { + (*vidsw[info->adp->va_index]->set_win_org)(info->adp, newbank*info->adp->va_window_size); + info->bank = newbank; + } + sofs %= info->adp->va_window_size; + bofs = x & 0x7; /* offset within byte */ + outw(GDCIDX, (0x8000 >> bofs) | 0x08); /* bit mask */ + outw(GDCIDX, (val << 8) | 0x00); /* set/reset */ + *(info->vidmem + sofs) ^= 0xff; /* read-modify-write */ break; - +#endif + case 8: - sofs += x + (info->swidth - info->width) / 2; + sofs += x; newbank = sofs/info->adp->va_window_size; if (info->bank != newbank) { (*vidsw[info->adp->va_index]->set_win_org)(info->adp, newbank*info->adp->va_window_size); @@ -390,7 +390,7 @@ bmp_DecodeRLE4(BMP_INFO *info, int line) /* ** bmp_DecodeRLE8 -** Given (data) pointing to a line of RLE4-format data and (line) being the starting +** Given (data) pointing to a line of RLE8-format data and (line) being the starting ** line onscreen, decode the line. */ static void @@ -450,12 +450,46 @@ static void bmp_DecodeLine(BMP_INFO *info, int line) { int x; + u_char val, mask, *p; switch(info->format) { case BI_RGB: - for (x = 0; x < info->width; x++, info->index++) - bmp_SetPix(info, x, line, *info->index); - info->index += 3 - (--x % 4); + switch(info->depth) { + case 8: + for (x = 0; x < info->width; x++, info->index++) + bmp_SetPix(info, x, line, *info->index); + info->index += 3 - (--x % 4); + break; + case 4: + p = info->index; + for (x = 0; x < info->width; x++) { + if (x & 1) { + val = *p & 0xf; /* get low nybble */ + p++; + } else { + val = *p >> 4; /* get high nybble */ + } + bmp_SetPix(info, x, line, val); + } + /* warning, this depends on integer truncation, do not hand-optimise! */ + info->index += ((x + 7) / 8) * 4; + break; + case 1: + p = info->index; + mask = 0x80; + for (x = 0; x < info->width; x++) { + val = (*p & mask) ? 1 : 0; + mask >>= 1; + if (mask == 0) { + mask = 0x80; + p++; + } + bmp_SetPix(info, x, line, val); + } + /* warning, this depends on integer truncation, do not hand-optimise! */ + info->index += ((x + 31) / 32) * 4; + break; + } break; case BI_RLE4: bmp_DecodeRLE4(info, line); @@ -507,6 +541,7 @@ bmp_Init(const char *data, int swidth, int sheight, int sdepth) /* image parameters */ bmp_info.width = bmf->bmfi.bmiHeader.biWidth; bmp_info.height = bmf->bmfi.bmiHeader.biHeight; + bmp_info.depth = bmf->bmfi.bmiHeader.biBitCount; bmp_info.format = bmf->bmfi.bmiHeader.biCompression; switch(bmp_info.format) { /* check compression format */ @@ -525,16 +560,13 @@ bmp_Init(const char *data, int swidth, int sheight, int sdepth) if (bmp_info.ncols == 0) { /* uses all of them */ bmp_info.ncols = 1 << bmf->bmfi.bmiHeader.biBitCount; } - if ((bmf->bmfi.bmiHeader.biBitCount != sdepth) - || (bmp_info.ncols > (1 << sdepth))) { - printf("splash_bmp: unsupported color depth (%d bits, %d colors)\n", - bmf->bmfi.bmiHeader.biBitCount, bmp_info.ncols); - return(1); - } if ((bmp_info.height > bmp_info.sheight) || (bmp_info.width > bmp_info.swidth) || (bmp_info.ncols > (1 << sdepth))) { - return(1); /* beyond screen capacity */ + if (bootverbose) + printf("splash_bmp: beyond screen capacity (%dx%d, %d colors)\n", + bmp_info.width, bmp_info.height, bmp_info.ncols); + return(1); } /* read palette */ @@ -556,6 +588,7 @@ static int bmp_Draw(video_adapter_t *adp) { int line; + int i; if (bmp_info.data == NULL) { /* init failed, do nothing */ return(1); @@ -564,17 +597,39 @@ bmp_Draw(video_adapter_t *adp) /* clear the screen */ bmp_info.vidmem = (u_char *)adp->va_window; bmp_info.adp = adp; - /* XXX; the following line is correct only for 8bpp modes */ - fill(&bmp_info, 0, 0, bmp_info.swidth, bmp_info.sheight); + (*vidsw[adp->va_index]->clear)(adp); (*vidsw[adp->va_index]->set_win_org)(adp, 0); bmp_info.bank = 0; /* initialise the info structure for drawing */ bmp_info.index = bmp_info.data; +#ifdef PC98 + bmp_info.prev_val = 255; +#endif /* set the palette for our image */ (*vidsw[adp->va_index]->load_palette)(adp, (u_char *)&bmp_info.palette); +#ifndef PC98 + /* XXX: this is ugly, but necessary for EGA/VGA 1bpp/4bpp modes */ + if ((adp->va_type == KD_EGA) || (adp->va_type == KD_VGA)) { + inb(adp->va_crtc_addr + 6); /* reset flip-flop */ + outb(ATC, 0x14); + outb(ATC, 0); + for (i = 0; i < 16; ++i) { + outb(ATC, i); + outb(ATC, i); + } + inb(adp->va_crtc_addr + 6); /* reset flip-flop */ + outb(ATC, 0x20); /* enable palette */ + + outw(GDCIDX, 0x0f01); /* set/reset enable */ + + if (bmp_info.sdepth == 1) + outw(TSIDX, 0x0102); /* unmask plane #0 */ + } +#endif + for (line = 0; (line < bmp_info.height) && bmp_info.index; line++) { bmp_DecodeLine(&bmp_info, line); } |
