📄 fbcon.c
字号:
static __inline__ void fast_memmove(char *dst, char *src, size_t size){ if (!size) return; if (dst < src) __asm__ __volatile__ ("1:" " moveml %0@+,%/d0/%/d1/%/a0/%/a1\n" " moveml %/d0/%/d1/%/a0/%/a1,%1@\n" " addql #8,%1; addql #8,%1\n" " dbra %2,1b\n" " clrw %2; subql #1,%2\n" " jcc 1b" : "=a" (src), "=a" (dst), "=d" (size) : "0" (src), "1" (dst), "2" (size / 16 - 1) : "d0", "d1", "a0", "a1", "memory"); else __asm__ __volatile__ ("1:" " subql #8,%0; subql #8,%0\n" " moveml %0@,%/d0/%/d1/%/a0/%/a1\n" " moveml %/d0/%/d1/%/a0/%/a1,%1@-\n" " dbra %2,1b\n" " clrw %2; subql #1,%2\n" " jcc 1b" : "=a" (src), "=a" (dst), "=d" (size) : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1) : "d0", "d1", "a0", "a1", "memory");}/* Sets the bytes in the visible column at d, height h, to the value * val for a 4 plane screen. The the bis of the color in 'color' are * moved (8 times) to the respective bytes. This means: * * for(h times; d += bpr) * *d = (color & 1) ? 0xff : 0; * *(d+2) = (color & 2) ? 0xff : 0; * *(d+4) = (color & 4) ? 0xff : 0; * *(d+6) = (color & 8) ? 0xff : 0; */static __inline__ void memclear_4p_col(void *d, size_t h, u_long val, int bpr){ __asm__ __volatile__ ("1: movepl %4,%0@(0)\n\t" "addal %5,%0\n\t" "dbra %1,1b" : "=a" (d), "=d" (h) : "0" (d), "1" (h - 1), "d" (val), "r" (bpr) );}/* Sets a 4 plane region from 'd', length 'count' bytes, to the color * in val1/val2. 'd' has to be an even address and count must be divisible * by 8, because only whole words and all planes are accessed. I.e.: * * for(count/8 times) * *d = *(d+1) = (color & 1) ? 0xff : 0; * *(d+2) = *(d+3) = (color & 2) ? 0xff : 0; * *(d+4) = *(d+5) = (color & 4) ? 0xff : 0; * *(d+6) = *(d+7) = (color & 8) ? 0xff : 0; */static __inline__ void memset_even_4p(void *d, size_t count, u_long val1, u_long val2){ u_long *dd = d; count /= 8; while (count--) { *dd++ = val1; *dd++ = val2; }}/* Copies a 4 plane column from 's', height 'h', to 'd'. */static __inline__ void memmove_4p_col (void *d, void *s, int h, int bpr){ u_char *dd = d, *ss = s; while (h--) { dd[0] = ss[0]; dd[2] = ss[2]; dd[4] = ss[4]; dd[6] = ss[6]; dd += bpr; ss += bpr; }}/* This expands a 4 bit color into a long for movepl (4 plane) operations. */static __inline__ u_long expand4l(u_char c){ u_long rv; __asm__ __volatile__ ("lsrb #1,%2\n\t" "scs %0\n\t" "lsll #8,%0\n\t" "lsrb #1,%2\n\t" "scs %0\n\t" "lsll #8,%0\n\t" "lsrb #1,%2\n\t" "scs %0\n\t" "lsll #8,%0\n\t" "lsrb #1,%2\n\t" "scs %0\n\t" : "=&d" (rv), "=d" (c) : "1" (c) ); return(rv);}/* This expands a 4 bit color into two longs for two movel operations * (4 planes). */static __inline__ void expand4dl(u_char c, u_long *ret1, u_long *ret2){ u_long rv1, rv2; __asm__ __volatile__ ("lsrb #1,%3\n\t" "scs %0\n\t" "extw %0\n\t" "swap %0\n\t" "lsrb #1,%3\n\t" "scs %0\n\t" "extw %0\n\t" "lsrb #1,%3\n\t" "scs %1\n\t" "extw %1\n\t" "swap %1\n\t" "lsrb #1,%3\n\t" "scs %1\n\t" "extw %1" : "=&d" (rv1), "=&d" (rv2), "=d" (c) : "2" (c) ); *ret1 = rv1; *ret2 = rv2;}/* This duplicates a byte 4 times into a long. */static __inline__ u_long dup4l(u_char c){ ushort tmp; ulong rv; __asm__ __volatile__ ("moveb %2,%0\n\t" "lslw #8,%0\n\t" "moveb %2,%0\n\t" "movew %0,%1\n\t" "swap %0\n\t" "movew %1,%0" : "=&d" (rv), "=d" (tmp) : "d" (c) ); return(rv);}/* Sets the bytes in the visible column at d, height h, to the value * val1,val2 for a 8 plane screen. The the bis of the color in 'color' are * moved (8 times) to the respective bytes. This means: * * for(h times; d += bpr) * *d = (color & 1) ? 0xff : 0; * *(d+2) = (color & 2) ? 0xff : 0; * *(d+4) = (color & 4) ? 0xff : 0; * *(d+6) = (color & 8) ? 0xff : 0; * *(d+8) = (color & 16) ? 0xff : 0; * *(d+10) = (color & 32) ? 0xff : 0; * *(d+12) = (color & 64) ? 0xff : 0; * *(d+14) = (color & 128) ? 0xff : 0; */static __inline__ void memclear_8p_col(void *d, size_t h, u_long val1, u_long val2, int bpr){ __asm__ __volatile__ ("1: movepl %4,%0@(0)\n\t" "movepl %5,%0@(8)\n\t" "addal %6,%0\n\t" "dbra %1,1b" : "=a" (d), "=d" (h) : "0" (d), "1" (h - 1), "d" (val1), "d" (val2), "r" (bpr) );}/* Sets a 8 plane region from 'd', length 'count' bytes, to the color * val1..val4. 'd' has to be an even address and count must be divisible * by 16, because only whole words and all planes are accessed. I.e.: * * for(count/16 times) * *d = *(d+1) = (color & 1) ? 0xff : 0; * *(d+2) = *(d+3) = (color & 2) ? 0xff : 0; * *(d+4) = *(d+5) = (color & 4) ? 0xff : 0; * *(d+6) = *(d+7) = (color & 8) ? 0xff : 0; * *(d+8) = *(d+9) = (color & 16) ? 0xff : 0; * *(d+10) = *(d+11) = (color & 32) ? 0xff : 0; * *(d+12) = *(d+13) = (color & 64) ? 0xff : 0; * *(d+14) = *(d+15) = (color & 128) ? 0xff : 0; */static __inline__ void memset_even_8p(void *d, size_t count, u_long val1, u_long val2, u_long val3, u_long val4){ u_long *dd = d; count /= 16; while (count--) { *dd++ = val1; *dd++ = val2; *dd++ = val3; *dd++ = val4; }}/* Copies a 8 plane column from 's', height 'h', to 'd'. */static __inline__ void memmove_8p_col (void *d, void *s, int h, int bpr){ u_char *dd = d, *ss = s; while (h--) { dd[0] = ss[0]; dd[2] = ss[2]; dd[4] = ss[4]; dd[6] = ss[6]; dd[8] = ss[8]; dd[10] = ss[10]; dd[12] = ss[12]; dd[14] = ss[14]; dd += bpr; ss += bpr; }}/* This expands a 8 bit color into two longs for two movepl (8 plane) * operations. */static __inline__ void expand8dl(u_char c, u_long *ret1, u_long *ret2){ u_long rv1, rv2; __asm__ __volatile__ ("lsrb #1,%3\n\t" "scs %0\n\t" "lsll #8,%0\n\t" "lsrb #1,%3\n\t" "scs %0\n\t" "lsll #8,%0\n\t" "lsrb #1,%3\n\t" "scs %0\n\t" "lsll #8,%0\n\t" "lsrb #1,%3\n\t" "scs %0\n\t" "lsrb #1,%3\n\t" "scs %1\n\t" "lsll #8,%1\n\t" "lsrb #1,%3\n\t" "scs %1\n\t" "lsll #8,%1\n\t" "lsrb #1,%3\n\t" "scs %1\n\t" "lsll #8,%1\n\t" "lsrb #1,%3\n\t" "scs %1" : "=&d" (rv1), "=&d" (rv2),"=d" (c) : "2" (c) ); *ret1 = rv1; *ret2 = rv2;}/* This expands a 8 bit color into four longs for four movel operations * (8 planes). *//* ++andreas: use macro to avoid taking address of return values */#define expand8ql(c, rv1, rv2, rv3, rv4) \do { u_char tmp = c; \ __asm__ __volatile__ \ ("lsrb #1,%5\n\t" \ "scs %0\n\t" \ "extw %0\n\t" \ "swap %0\n\t" \ "lsrb #1,%5\n\t" \ "scs %0\n\t" \ "extw %0\n\t" \ "lsrb #1,%5\n\t" \ "scs %1\n\t" \ "extw %1\n\t" \ "swap %1\n\t" \ "lsrb #1,%5\n\t" \ "scs %1\n\t" \ "extw %1\n\t" \ "lsrb #1,%5\n\t" \ "scs %2\n\t" \ "extw %2\n\t" \ "swap %2\n\t" \ "lsrb #1,%5\n\t" \ "scs %2\n\t" \ "extw %2\n\t" \ "lsrb #1,%5\n\t" \ "scs %3\n\t" \ "extw %3\n\t" \ "swap %3\n\t" \ "lsrb #1,%5\n\t" \ "scs %3\n\t" \ "extw %3" \ : "=&d" (rv1), "=&d" (rv2), "=&d" (rv3), \ "=&d" (rv4), "=d" (tmp) \ : "4" (tmp) \ ); \} while (0)/* Sets the bytes in the visible column at d, height h, to the value * val for a 2 plane screen. The the bis of the color in 'color' are * moved (8 times) to the respective bytes. This means: * * for(h times; d += bpr) * *d = (color & 1) ? 0xff : 0; * *(d+2) = (color & 2) ? 0xff : 0; */static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, int bpr){ __asm__ __volatile__ ("1: movepw %4,%0@(0)\n\t" "addal %5,%0\n\t" "dbra %1,1b" : "=a" (d), "=d" (h) : "0" (d), "1" (h - 1), "d" (val), "r" (bpr) );}/* Sets a 2 plane region from 'd', length 'count' bytes, to the color * in val1. 'd' has to be an even address and count must be divisible * by 8, because only whole words and all planes are accessed. I.e.: * * for(count/4 times) * *d = *(d+1) = (color & 1) ? 0xff : 0; * *(d+2) = *(d+3) = (color & 2) ? 0xff : 0; */static __inline__ void memset_even_2p(void *d, size_t count, u_long val){ u_long *dd = d; count /= 4; while (count--) *dd++ = val;}/* Copies a 2 plane column from 's', height 'h', to 'd'. */static __inline__ void memmove_2p_col (void *d, void *s, int h, int bpr){ u_char *dd = d, *ss = s; while (h--) { dd[0] = ss[0]; dd[2] = ss[2]; dd += bpr; ss += bpr; }}/* This expands a 2 bit color into a short for movepw (2 plane) operations. */static __inline__ u_short expand2w(u_char c){ u_short rv; __asm__ __volatile__ ("lsrb #1,%2\n\t" "scs %0\n\t" "lsll #8,%0\n\t" "lsrb #1,%2\n\t" "scs %0\n\t" : "=&d" (rv), "=d" (c) : "1" (c) ); return(rv);}/* This expands a 2 bit color into one long for a movel operation * (2 planes). */static __inline__ u_long expand2l(u_char c){ u_long rv; __asm__ __volatile__ ("lsrb #1,%2\n\t" "scs %0\n\t" "extw %0\n\t" "swap %0\n\t" "lsrb #1,%2\n\t" "scs %0\n\t" "extw %0\n\t" : "=&d" (rv), "=d" (c) : "1" (c) ); return rv;}/* This duplicates a byte 2 times into a short. */static __inline__ u_short dup2w(u_char c){ ushort rv; __asm__ __volatile__ ( "moveb %1,%0\n\t" "lslw #8,%0\n\t" "moveb %1,%0\n\t" : "=&d" (rv) : "d" (c) ); return( rv );}/* ====================================================================== *//* fbcon_XXX routines - interface used by the world * * This system is now divided into two levels because of complications * caused by hardware scrolling. Top level functions: * * fbcon_bmove(), fbcon_clear(), fbcon_putc() * * handles y values in range [0, scr_height-1] that correspond to real * screen positions. y_wrap shift means that first line of bitmap may be * anywhere on this display. These functions convert lineoffsets to * bitmap offsets and deal with the wrap-around case by splitting blits. * * fbcon_bmove_physical_8() -- These functions fast implementations * fbcon_clear_physical_8() -- of original fbcon_XXX fns. * fbcon_putc_physical_8() -- (fontwidth != 8) may be added later * * WARNING: *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -