aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2020-09-17 07:43:57 +0200
committerHelge Deller <deller@gmx.de>2020-09-17 07:43:57 +0200
commitccb1665f9c07765b19d8c884e1e2707530ea6bec (patch)
tree980a1f6f41036b54cb525ef23c79659065df1e4b
parentb89c697b9c66398b7c9b336ed251ff447f5b8de9 (diff)
downloadseabios-hppa-master-old.zip
seabios-hppa-master-old.tar.gz
seabios-hppa-master-old.tar.bz2
parisc: Alloc any font size with STI font_unpmv functionmaster-old
The font_unpmv function was limited to 8x16 fonts. This change now allows it to render fonts of any size up to 32x32 pixels. Millicode functions which do not reside inside the STI code will not get copied at runtime into userspace RAM, and as such we can not call millicode functions from within STI code. But the compiler will usually emit a call to the mulI millicode routine for any multiplication with an variable integer value, so I had to write a mulI implementation using shifts, which seems to be pretty good optimized by the compiler. Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--src/parisc/sticore.h2
-rw-r--r--src/parisc/stirom.c48
2 files changed, 43 insertions, 7 deletions
diff --git a/src/parisc/sticore.h b/src/parisc/sticore.h
index 8c3a98a..3e38ff0 100644
--- a/src/parisc/sticore.h
+++ b/src/parisc/sticore.h
@@ -224,7 +224,7 @@ struct sti_rom_font {
struct font {
struct sti_rom_font hdr;
- char font[16*256];
+ unsigned char font[16*256];
};
/* STI font printing function structs */
diff --git a/src/parisc/stirom.c b/src/parisc/stirom.c
index 90eac00..07e89c3 100644
--- a/src/parisc/stirom.c
+++ b/src/parisc/stirom.c
@@ -370,29 +370,65 @@ static u32 __stifunc("block_move") sti_bmove(struct sti_blkmv_flags *flags,
return 0;
}
+/* can not call millicode routines in STI ROM code */
+static inline int inline_mul(int val, int mul)
+{
+ switch (mul) {
+ case 7: return (val << 3) - val;
+ case 6: return (val << 2) + (val << 1);
+ case 5: return (val << 2) + val;
+ case 4: return (val << 2);
+ case 3: return (val << 1) + val;
+ case 2: return (val << 1);
+ case 1: return val;
+ case 0: return 0;
+ default: return 0;
+ }
+}
+
static int __stifunc("font_unpmv") sti_font_unpmv(struct sti_font_flags *flags,
struct sti_font_inptr *in,
struct sti_font_outptr *out,
struct sti_glob_cfg *cfg)
{
- unsigned char *src = (unsigned char *)in->font_start_addr \
- + sizeof(struct sti_rom_font) + (in->index * 16);
- int y;
+ struct font *font = (struct font *) in->font_start_addr;
+ int bpc = font->hdr.bytes_per_char;
+ int width = font->hdr.width;
+ unsigned char *src;
+ int c, y, pitch;
(void)flags;
+ /* same as: src = &font->font[in->index * bpc]; */
+ c = in->index;
+ y = inline_mul(c, bpc & 7);
+ if (bpc & 8) y += c << 3;
+ if (bpc & 16) y += c << 4;
+ if (bpc & 32) y += c << 5;
+ if (bpc & 64) y += c << 6;
+ if (bpc & 128) y += c << 7;
+ src = &font->font[y];
+
write_artist(cfg, ARTIST_VRAM_IDX,
(in->dest_y << 13) | (in->dest_x << 2));
write_artist(cfg, ARTIST_FGCOLOR, in->fg_color);
write_artist(cfg, ARTIST_BGCOLOR, in->bg_color);
write_artist(cfg, ARTIST_BITMAP_OP, 0x23000300);
- write_artist(cfg, ARTIST_VRAM_BITMASK, 0xff000000);
+ write_artist(cfg, ARTIST_VRAM_BITMASK, 0xffffffff << (32 - width));
write_artist(cfg, ARTIST_DST_BM_ACCESS, 0x2ea01000);
write_artist(cfg, ARTIST_PLANE_BITMASK, 7);
barrier();
- for(y = 0; y < 16; y++) {
- write_artist(cfg, ARTIST_VRAM_BYTE_WRITE, src[y] << 24);
+ pitch = (width + 7) / 8;
+ for (y = 0; y < bpc; y += pitch) {
+ u32 val = 0;
+ switch (pitch) {
+ case 4: val |= src[y+3] << 0; /* fall through */
+ case 3: val |= src[y+2] << 8; /* fall through */
+ case 2: val |= src[y+1] << 16; /* fall through */
+ default: val |= src[y+0] << 24; /* fall through */
+ }
+ write_artist(cfg, ARTIST_VRAM_BYTE_WRITE, val);
barrier();
}
out->errno = 0;