📄 amifb.c
字号:
#define FMODE_BSCAN2 (0x4000) /* Use PF2 modulus every other line */#define FMODE_SPAGEM (0x0008) /* Sprite page mode */#define FMODE_SPR32 (0x0004) /* Sprite 32 bit fetch */#define FMODE_BPAGEM (0x0002) /* Bitplane page mode */#define FMODE_BPL32 (0x0001) /* Bitplane 32 bit fetch */ /* * Tags used to indicate a specific Pixel Clock * * clk_shift is the shift value to get the timings in 35 ns units */enum { TAG_SHRES, TAG_HIRES, TAG_LORES }; /* * Tags used to indicate the specific chipset */enum { TAG_OCS, TAG_ECS, TAG_AGA }; /* * Tags used to indicate the memory bandwidth */enum { TAG_FMODE_1, TAG_FMODE_2, TAG_FMODE_4 }; /* * Clock Definitions, Maximum Display Depth * * These depend on the E-Clock or the Chipset, so they are filled in * dynamically */static u_long pixclock[3]; /* SHRES/HIRES/LORES: index = clk_shift */static u_short maxdepth[3]; /* SHRES/HIRES/LORES: index = clk_shift */static u_short maxfmode, chipset; /* * Broadcast Video Timings * * Horizontal values are in 35 ns (SHRES) units * Vertical values are in interlaced scanlines */#define PAL_DIWSTRT_H (360) /* PAL Window Limits */#define PAL_DIWSTRT_V (48)#define PAL_HTOTAL (1816)#define PAL_VTOTAL (625)#define NTSC_DIWSTRT_H (360) /* NTSC Window Limits */#define NTSC_DIWSTRT_V (40)#define NTSC_HTOTAL (1816)#define NTSC_VTOTAL (525) /* * Various macros */#define up2(v) (((v)+1) & -2)#define down2(v) ((v) & -2)#define div2(v) ((v)>>1)#define mod2(v) ((v) & 1)#define up4(v) (((v)+3) & -4)#define down4(v) ((v) & -4)#define mul4(v) ((v)<<2)#define div4(v) ((v)>>2)#define mod4(v) ((v) & 3)#define up8(v) (((v)+7) & -8)#define down8(v) ((v) & -8)#define div8(v) ((v)>>3)#define mod8(v) ((v) & 7)#define up16(v) (((v)+15) & -16)#define down16(v) ((v) & -16)#define div16(v) ((v)>>4)#define mod16(v) ((v) & 15)#define up32(v) (((v)+31) & -32)#define down32(v) ((v) & -32)#define div32(v) ((v)>>5)#define mod32(v) ((v) & 31)#define up64(v) (((v)+63) & -64)#define down64(v) ((v) & -64)#define div64(v) ((v)>>6)#define mod64(v) ((v) & 63)#define upx(x,v) (((v)+(x)-1) & -(x))#define downx(x,v) ((v) & -(x))#define modx(x,v) ((v) & ((x)-1))/* if x1 is not a constant, this macro won't make real sense :-) */#ifdef __mc68000__#define DIVUL(x1, x2) ({int res; asm("divul %1,%2,%3": "=d" (res): \ "d" (x2), "d" ((long)((x1)/0x100000000ULL)), "0" ((long)(x1))); res;})#else/* We know a bit about the numbers, so we can do it this way */#define DIVUL(x1, x2) ((((long)((unsigned long long)x1 >> 8) / x2) << 8) + \ ((((long)((unsigned long long)x1 >> 8) % x2) << 8) / x2))#endif#define highw(x) ((u_long)(x)>>16 & 0xffff)#define loww(x) ((u_long)(x) & 0xffff)#define custom amiga_custom#define VBlankOn() custom.intena = IF_SETCLR|IF_COPER#define VBlankOff() custom.intena = IF_COPER /* * Chip RAM we reserve for the Frame Buffer * * This defines the Maximum Virtual Screen Size * (Setable per kernel options?) */#define VIDEOMEMSIZE_AGA_2M (1310720) /* AGA (2MB) : max 1280*1024*256 */#define VIDEOMEMSIZE_AGA_1M (786432) /* AGA (1MB) : max 1024*768*256 */#define VIDEOMEMSIZE_ECS_2M (655360) /* ECS (2MB) : max 1280*1024*16 */#define VIDEOMEMSIZE_ECS_1M (393216) /* ECS (1MB) : max 1024*768*16 */#define VIDEOMEMSIZE_OCS (262144) /* OCS : max ca. 800*600*16 */#define SPRITEMEMSIZE (64*64/4) /* max 64*64*4 */#define DUMMYSPRITEMEMSIZE (8)static u_long spritememory;#define CHIPRAM_SAFETY_LIMIT (16384)static u_long videomemory; /* * This is the earliest allowed start of fetching display data. * Only if you really want no hardware cursor and audio, * set this to 128, but let it better at 192 */static u_long min_fstrt = 192;#define assignchunk(name, type, ptr, size) \{ \ (name) = (type)(ptr); \ ptr += size; \} /* * Copper Instructions */#define CMOVE(val, reg) (CUSTOM_OFS(reg)<<16 | (val))#define CMOVE2(val, reg) ((CUSTOM_OFS(reg)+2)<<16 | (val))#define CWAIT(x, y) (((y) & 0x1fe)<<23 | ((x) & 0x7f0)<<13 | 0x0001fffe)#define CEND (0xfffffffe)typedef union { u_long l; u_short w[2];} copins;static struct copdisplay { copins *init; copins *wait; copins *list[2][2]; copins *rebuild[2];} copdisplay;static u_short currentcop = 0; /* * Hardware Cursor API Definitions * These used to be in linux/fb.h, but were preliminary and used by * amifb only anyway */#define FBIOGET_FCURSORINFO 0x4607#define FBIOGET_VCURSORINFO 0x4608#define FBIOPUT_VCURSORINFO 0x4609#define FBIOGET_CURSORSTATE 0x460A#define FBIOPUT_CURSORSTATE 0x460Bstruct fb_fix_cursorinfo { __u16 crsr_width; /* width and height of the cursor in */ __u16 crsr_height; /* pixels (zero if no cursor) */ __u16 crsr_xsize; /* cursor size in display pixels */ __u16 crsr_ysize; __u16 crsr_color1; /* colormap entry for cursor color1 */ __u16 crsr_color2; /* colormap entry for cursor color2 */};struct fb_var_cursorinfo { __u16 width; __u16 height; __u16 xspot; __u16 yspot; __u8 data[1]; /* field with [height][width] */};struct fb_cursorstate { __s16 xoffset; __s16 yoffset; __u16 mode;};#define FB_CURSOR_OFF 0#define FB_CURSOR_ON 1#define FB_CURSOR_FLASH 2 /* * Hardware Cursor */static int cursorrate = 20; /* Number of frames/flash toggle */static u_short cursorstate = -1;static u_short cursormode = FB_CURSOR_OFF;static u_short *lofsprite, *shfsprite, *dummysprite; /* * Current Video Mode */static struct amifb_par { /* General Values */ int xres; /* vmode */ int yres; /* vmode */ int vxres; /* vmode */ int vyres; /* vmode */ int xoffset; /* vmode */ int yoffset; /* vmode */ u_short bpp; /* vmode */ u_short clk_shift; /* vmode */ u_short line_shift; /* vmode */ int vmode; /* vmode */ u_short diwstrt_h; /* vmode */ u_short diwstop_h; /* vmode */ u_short diwstrt_v; /* vmode */ u_short diwstop_v; /* vmode */ u_long next_line; /* modulo for next line */ u_long next_plane; /* modulo for next plane */ /* Cursor Values */ struct { short crsr_x; /* movecursor */ short crsr_y; /* movecursor */ short spot_x; short spot_y; u_short height; u_short width; u_short fmode; } crsr; /* OCS Hardware Registers */ u_long bplpt0; /* vmode, pan (Note: physical address) */ u_long bplpt0wrap; /* vmode, pan (Note: physical address) */ u_short ddfstrt; u_short ddfstop; u_short bpl1mod; u_short bpl2mod; u_short bplcon0; /* vmode */ u_short bplcon1; /* vmode */ u_short htotal; /* vmode */ u_short vtotal; /* vmode */ /* Additional ECS Hardware Registers */ u_short bplcon3; /* vmode */ u_short beamcon0; /* vmode */ u_short hsstrt; /* vmode */ u_short hsstop; /* vmode */ u_short hbstrt; /* vmode */ u_short hbstop; /* vmode */ u_short vsstrt; /* vmode */ u_short vsstop; /* vmode */ u_short vbstrt; /* vmode */ u_short vbstop; /* vmode */ u_short hcenter; /* vmode */ /* Additional AGA Hardware Registers */ u_short fmode; /* vmode */} currentpar;static struct fb_info fb_info = { .fix = { .id = "Amiga ", .visual = FB_VISUAL_PSEUDOCOLOR, .accel = FB_ACCEL_AMIGABLITT }}; /* * Saved color entry 0 so we can restore it when unblanking */static u_char red0, green0, blue0;#if defined(CONFIG_FB_AMIGA_ECS)static u_short ecs_palette[32];#endif /* * Latches for Display Changes during VBlank */static u_short do_vmode_full = 0; /* Change the Video Mode */static u_short do_vmode_pan = 0; /* Update the Video Mode */static short do_blank = 0; /* (Un)Blank the Screen (±1) */static u_short do_cursor = 0; /* Move the Cursor */ /* * Various Flags */static u_short is_blanked = 0; /* Screen is Blanked */static u_short is_lace = 0; /* Screen is laced */ /* * Predefined Video Modes * */static struct fb_videomode ami_modedb[] __initdata = { /* * AmigaOS Video Modes * * If you change these, make sure to update DEFMODE_* as well! */ { /* 640x200, 15 kHz, 60 Hz (NTSC) */ "ntsc", 60, 640, 200, TAG_HIRES, 106, 86, 44, 16, 76, 2, FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */ "ntsc-lace", 60, 640, 400, TAG_HIRES, 106, 86, 88, 33, 76, 4, FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { /* 640x256, 15 kHz, 50 Hz (PAL) */ "pal", 50, 640, 256, TAG_HIRES, 106, 86, 40, 14, 76, 2, FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x512, 15 kHz, 50 Hz interlaced (PAL) */ "pal-lace", 50, 640, 512, TAG_HIRES, 106, 86, 80, 29, 76, 4, FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { /* 640x480, 29 kHz, 57 Hz */ "multiscan", 57, 640, 480, TAG_SHRES, 96, 112, 29, 8, 72, 8, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x960, 29 kHz, 57 Hz interlaced */ "multiscan-lace", 57, 640, 960, TAG_SHRES, 96, 112, 58, 16, 72, 16, 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { /* 640x200, 15 kHz, 72 Hz */ "euro36", 72, 640, 200, TAG_HIRES, 92, 124, 6, 6, 52, 5, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x400, 15 kHz, 72 Hz interlaced */ "euro36-lace", 72, 640, 400, TAG_HIRES, 92, 124, 12, 12, 52, 10, 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { /* 640x400, 29 kHz, 68 Hz */ "euro72", 68, 640, 400, TAG_SHRES, 164, 92, 9, 9, 80, 8, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x800, 29 kHz, 68 Hz interlaced */ "euro72-lace", 68, 640, 800, TAG_SHRES, 164, 92, 18, 18, 80, 16, 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { /* 800x300, 23 kHz, 70 Hz */ "super72", 70, 800, 300, TAG_SHRES, 212, 140, 10, 11, 80, 7, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 800x600, 23 kHz, 70 Hz interlaced */ "super72-lace", 70, 800, 600, TAG_SHRES, 212, 140, 20, 22, 80, 14, 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { /* 640x200, 27 kHz, 57 Hz doublescan */ "dblntsc", 57, 640, 200, TAG_SHRES, 196, 124, 18, 17, 80, 4, 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP }, { /* 640x400, 27 kHz, 57 Hz */ "dblntsc-ff", 57, 640, 400, TAG_SHRES, 196, 124, 36, 35, 80, 7, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x800, 27 kHz, 57 Hz interlaced */ "dblntsc-lace", 57, 640, 800, TAG_SHRES, 196, 124, 72, 70, 80, 14, 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { /* 640x256, 27 kHz, 47 Hz doublescan */ "dblpal", 47, 640, 256, TAG_SHRES, 196, 124, 14, 13, 80, 4, 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP }, { /* 640x512, 27 kHz, 47 Hz */ "dblpal-ff", 47, 640, 512, TAG_SHRES, 196, 124, 28, 27, 80, 7, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x1024, 27 kHz, 47 Hz interlaced */ "dblpal-lace", 47, 640, 1024, TAG_SHRES, 196, 124, 56, 54, 80, 14, 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, /* * VGA Video Modes */ { /* 640x480, 31 kHz, 60 Hz (VGA) */ "vga", 60, 640, 480, TAG_SHRES, 64, 96, 30, 9, 112, 2, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 640x400, 31 kHz, 70 Hz (VGA) */ "vga70", 70, 640, 400, TAG_SHRES, 64, 96, 35, 12, 112, 2, FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP },#if 0 /* * A2024 video modes * These modes don't work yet because there's no A2024 driver. */ { /* 1024x800, 10 Hz */ "a2024-10", 10, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { /* 1024x800, 15 Hz */ "a2024-15", 15, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0, 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }#endif};#define NUM_TOTAL_MODES ARRAY_SIZE(ami_modedb)static char *mode_option __initdata = NULL;static int round_down_bpp = 1; /* for mode probing */ /* * Some default modes */#define DEFMODE_PAL 2 /* "pal" for PAL OCS/ECS */#define DEFMODE_NTSC 0 /* "ntsc" for NTSC OCS/ECS */#define DEFMODE_AMBER_PAL 3 /* "pal-lace" for flicker fixed PAL (A3000) */#define DEFMODE_AMBER_NTSC 1 /* "ntsc-lace" for flicker fixed NTSC (A3000) */#define DEFMODE_AGA 19 /* "vga70" for AGA */static int amifb_ilbm = 0; /* interleaved or normal bitplanes */static int amifb_inverse = 0; /* * Macros for the conversion from real world values to hardware register * values * * This helps us to keep our attention on the real stuff... *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -