1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546 |
- /* VGAlib version 1.1 - (c) 1992 Tommy Frandsen */
- /* */
- /* This library is free software; you can redistribute it and/or */
- /* modify it without any restrictions. This library is distributed */
- /* in the hope that it will be useful, but without any warranty; */
- /* without even the implied warranty of merchantability or fitness */
- /* for a particular purpose. */
- #include "vga.h"
- #include <stdio.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <termios.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/mman.h>
- #include <sys/kd.h>
- #include <linux/mm.h>
- #undef free
- #include <stdlib.h>
- #define char unsigned char
- #define GRAPH_BASE 0xA0000
- #define GRAPH_SIZE 0x10000
- #define FONT_BASE 0xA0000
- #define FONT_SIZE 0x2000
- #define NULL_SIZE 0x1000
- #define MAX_REGS 100
- /* VGA index register ports */
- #define CRT_IC 0x3D4 /* CRT Controller Index - color emulation */
- #define CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */
- #define ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */
- #define GRA_I 0x3CE /* Graphics Controller Index */
- #define SEQ_I 0x3C4 /* Sequencer Index */
- #define PEL_IW 0x3C8 /* PEL Write Index */
- #define PEL_IR 0x3C7 /* PEL Read Index */
- /* VGA data register ports */
- #define CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */
- #define CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */
- #define ATT_R 0x3C1 /* Attribute Controller Data Read Register */
- #define GRA_D 0x3CF /* Graphics Controller Data Register */
- #define SEQ_D 0x3C5 /* Sequencer Data Register */
- #define MIS_R 0x3CC /* Misc Output Read Register */
- #define MIS_W 0x3C2 /* Misc Output Write Register */
- #define IS1_RC 0x3DA /* Input Status Register 1 - color emulation */
- #define IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */
- #define PEL_D 0x3C9 /* PEL Data Register */
- /* VGA indexes max counts */
- #define CRT_C 24 /* 24 CRT Controller Registers */
- #define ATT_C 21 /* 21 Attribute Controller Registers */
- #define GRA_C 9 /* 9 Graphics Controller Registers */
- #define SEQ_C 5 /* 5 Sequencer Registers */
- #define MIS_C 1 /* 1 Misc Output Register */
-
- /* VGA registers saving indexes */
- #define CRT 0 /* CRT Controller Registers start */
- #define ATT CRT+CRT_C /* Attribute Controller Registers start */
- #define GRA ATT+ATT_C /* Graphics Controller Registers start */
- #define SEQ GRA+GRA_C /* Sequencer Registers */
- #define MIS SEQ+SEQ_C /* General Registers */
- #define EXT MIS+MIS_C /* SVGA Extended Registers */
- #define SEG_SELECT 0x3CD
- #define ABS(a) (((a)<0) ? -(a) : (a))
- /* variables used to shift between monchrome and color emulation */
- static int CRT_I; /* current CRT index register address */
- static int CRT_D; /* current CRT data register address */
- static int IS1_R; /* current input status register address */
- static int color_text; /* true if color text emulation */
- /* graphics mode information */
- struct info {
- int xdim;
- int ydim;
- int colors;
- int xbytes;
- };
- /* BIOS mode 0Dh - 320x200x16 */
- static char g320x200x16_regs[60] = {
- 0x2D,0x27,0x28,0x90,0x2B,0x80,0xBF,0x1F,0x00,0xC0,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x9C,0x8E,0x8F,0x14,0x00,0x96,0xB9,0xE3,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
- 0x00,0x0F,0x00,0x20,0x00,0x00,0x05,0x0F,0xFF,
- 0x03,0x09,0x0F,0x00,0x06,
- 0x63
- };
- static struct info g320x200x16_info = { 320, 200, 16, 40 };
- /* BIOS mode 0Eh - 640x200x16 */
- static char g640x200x16_regs[60] = {
- 0x5F,0x4F,0x50,0x82,0x54,0x80,0xBF,0x1F,0x00,0xC0,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x9C,0x8E,0x8F,0x28,0x00,0x96,0xB9,0xE3,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
- 0x00,0x0F,0x00,0x20,0x00,0x00,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x06,
- 0x63
- };
- static struct info g640x200x16_info = { 640, 200, 16, 80 };
- /* BIOS mode 10h - 640x350x16 */
- static char g640x350x16_regs[60] = {
- 0x5F,0x4F,0x50,0x82,0x54,0x80,0xBF,0x1F,0x00,0x40,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x83,0x85,0x5D,0x28,0x0F,0x63,0xBA,0xE3,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
- 0x00,0x0F,0x00,0x20,0x00,0x00,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x06,
- 0xA3
- };
- static struct info g640x350x16_info = { 640, 350, 16, 80 };
- /* BIOS mode 12h - 640x480x16 */
- static char g640x480x16_regs[60] = {
- 0x5F,0x4F,0x50,0x82,0x54,0x80,0x0B,0x3E,0x00,0x40,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xEA,0x8C,0xDF,0x28,0x00,0xE7,0x04,0xE3,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
- 0x00,0x0F,0x00,0x20,0x00,0x00,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x06,
- 0xE3
- };
- static struct info g640x480x16_info = { 640, 480, 16, 80 };
- /* BIOS mode 13h - 320x200x256 */
- static char g320x200x256_regs[60] = {
- 0x5F,0x4F,0x50,0x82,0x54,0x80,0xBF,0x1F,0x00,0x41,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x9C,0x8E,0x8F,0x28,0x40,0x96,0xB9,0xA3,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x41,0x00,0x0F,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x0E,
- 0x63
- };
- static struct info g320x200x256_info = { 320, 200, 256, 320 };
- /* non-BIOS mode - 320x240x256 */
- static char g320x240x256_regs[60] = {
- 0x5F,0x4F,0x50,0x82,0x54,0x80,0x0D,0x3E,0x00,0x41,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xEA,0xAC,0xDF,0x28,0x00,0xE7,0x06,0xE3,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x41,0x00,0x0F,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x06,
- 0xE3
- };
- static struct info g320x240x256_info = { 320, 240, 256, 80 };
- /* non-BIOS mode - 320x400x256 */
- static char g320x400x256_regs[60] = {
- 0x5F,0x4F,0x50,0x82,0x54,0x80,0xBF,0x1F,0x00,0x40,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x9C,0x8E,0x8F,0x28,0x00,0x96,0xB9,0xE3,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x41,0x00,0x0F,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x06,
- 0x63
- };
- static struct info g320x400x256_info = { 320, 400, 256, 80 };
- /* non-BIOS mode - 360x480x256 */
- static char g360x480x256_regs[60] = {
- 0x6B,0x59,0x5A,0x8E,0x5E,0x8A,0x0D,0x3E,0x00,0x40,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xEA,0xAC,0xDF,0x2D,0x00,0xE7,0x06,0xE3,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x41,0x00,0x0F,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x06,
- 0xE7
- };
- static struct info g360x480x256_info = { 360, 480, 256, 90 };
- /* monochrome mode based on BIOS mode 12h - 640x480x2 */
- static char g640x480x2_regs[60] = {
- 0x5F,0x4F,0x50,0x82,0x54,0x80,0x0B,0x3E,0x00,0x40,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xEA,0x8C,0xDF,0x28,0x00,0xE7,0x04,0xE3,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
- 0x00,0x0F,0x00,0x20,0x00,0x00,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x06,
- 0xE3
- };
- static struct info g640x480x2_info = { 640, 480, 2, 80 };
- /* ET4000 non-BIOS mode - 640x480x256 */
- static char g640x480x256_regs[70] = {
- 0x5F,0x4F,0x52,0x9F,0x53,0x1F,0x0B,0x3E,0x00,0x40,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xEB,0x2D,0xDF,0x80,0x60,0xEB,0xEC,0xAB,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x0C,
- 0xE3,
- 0x70,0x00,0x00,0x10,0x43,0x1F,0xAC,0x01,0x22,0x80
- };
- static struct info g640x480x256_info = { 640, 480, 256, 1024 };
- /* ET4000 non-BIOS mode - 800x600x256 */
- static char g800x600x256_regs[70] = {
- 0x7B,0x63,0x66,0x90,0x67,0x90,0x6F,0xF0,0x00,0x60,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x59,0x2B,0x57,0x80,0x60,0x59,0x5A,0xAB,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x0E,
- 0xEF,
- 0x70,0x00,0x00,0x10,0x43,0x1F,0xAC,0x01,0x22,0x80
- };
- static struct info g800x600x256_info = { 800, 600, 256, 1024 };
- /* ET4000 non-BIOS mode - 1024x768x256 */
- static char g1024x768x256_regs[70] = {
- 0x99,0x7F,0x82,0x97,0x83,0x17,0x2F,0xFD,0x00,0x60,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x01,0x29,0xFF,0x80,0x60,0x01,0x02,0xAB,
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
- 0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
- 0x03,0x01,0x0F,0x00,0x0C,
- 0x27,
- 0x70,0x00,0x02,0x90,0x43,0x1F,0xAC,0x01,0x99,0x80
- };
- static struct info g1024x768x256_info = { 1024, 768, 256, 1024 };
- /* default palette values */
- static char default_red[256]
- = { 0, 0, 0, 0,42,42,42,42,21,21,21,21,63,63,63,63,
- 0, 5, 8,11,14,17,20,24,28,32,36,40,45,50,56,63,
- 0,16,31,47,63,63,63,63,63,63,63,63,63,47,31,16,
- 0, 0, 0, 0, 0, 0, 0, 0,31,39,47,55,63,63,63,63,
- 63,63,63,63,63,55,47,39,31,31,31,31,31,31,31,31,
- 45,49,54,58,63,63,63,63,63,63,63,63,63,58,54,49,
- 45,45,45,45,45,45,45,45, 0, 7,14,21,28,28,28,28,
- 28,28,28,28,28,21,14, 7, 0, 0, 0, 0, 0, 0, 0, 0,
- 14,17,21,24,28,28,28,28,28,28,28,28,28,24,21,17,
- 14,14,14,14,14,14,14,14,20,22,24,26,28,28,28,28,
- 28,28,28,28,28,26,24,22,20,20,20,20,20,20,20,20,
- 0, 4, 8,12,16,16,16,16,16,16,16,16,16,12, 8, 4,
- 0, 0, 0, 0, 0, 0, 0, 0, 8,10,12,14,16,16,16,16,
- 16,16,16,16,16,14,12,10, 8, 8, 8, 8, 8, 8, 8, 8,
- 11,12,13,15,16,16,16,16,16,16,16,16,16,15,13,12,
- 11,11,11,11,11,11,11,11, 0, 0, 0, 0, 0, 0, 0, 0};
- static char default_green[256]
- = { 0, 0,42,42, 0, 0,21,42,21,21,63,63,21,21,63,63,
- 0, 5, 8,11,14,17,20,24,28,32,36,40,45,50,56,63,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,16,31,47,63,63,63,63,
- 63,63,63,63,63,47,31,16,31,31,31,31,31,31,31,31,
- 31,39,47,55,63,63,63,63,63,63,63,63,63,55,47,39,
- 45,45,45,45,45,45,45,45,45,49,54,58,63,63,63,63,
- 63,63,63,63,63,58,54,49, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7,14,21,29,28,28,28,28,28,28,28,28,21,14, 7,
- 14,14,14,14,14,14,14,14,14,17,21,24,28,28,28,28,
- 28,28,28,28,28,24,21,17,20,20,20,20,20,20,20,20,
- 20,22,24,26,28,28,28,28,28,28,28,28,28,26,24,22,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8,12,16,16,16,16,
- 16,16,16,16,16,12, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8,
- 8,10,12,14,16,16,16,16,16,16,16,16,16,14,12,10,
- 11,11,11,11,11,11,11,11,11,12,13,15,16,16,16,16,
- 16,16,16,16,16,15,13,12, 0, 0, 0, 0, 0, 0, 0, 0};
- static char default_blue[256]
- = { 0,42, 0,42, 0,42, 0,42,21,63,21,63,21,63,21,63,
- 0, 5, 8,11,14,17,20,24,28,32,36,40,45,50,56,63,
- 63,63,63,63,63,47,31,16, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,16,31,47,63,63,63,63,63,63,63,63,63,55,47,39,
- 31,31,31,31,31,31,31,31,31,39,47,55,63,63,63,63,
- 63,63,63,63,63,58,54,49,45,45,45,45,45,45,45,45,
- 45,49,54,58,63,63,63,63,28,28,28,28,28,21,14, 7,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,14,21,28,28,28,28,
- 28,28,28,28,28,24,21,17,14,14,14,14,14,14,14,14,
- 14,17,21,24,28,28,28,28,28,28,28,28,28,26,24,22,
- 20,20,20,20,20,20,20,20,20,22,24,26,28,28,28,28,
- 16,16,16,16,16,12, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 4, 8,12,16,16,16,16,16,16,16,16,16,14,12,10,
- 8, 8, 8, 8, 8, 8, 8, 8, 8,10,12,14,16,16,16,16,
- 16,16,16,16,16,15,13,12,11,11,11,11,11,11,11,11,
- 11,12,13,15,16,16,16,16, 0, 0, 0, 0, 0, 0, 0, 0};
- /* used to decompose color value into bits (for fast scanline drawing) */
- union bits {
- struct {
- char bit3;
- char bit2;
- char bit1;
- char bit0;
- } b;
- unsigned int i;
- };
- /* color decompositions */
- static union bits color16[16] = {{0,0,0,0},
- {0,0,0,1},
- {0,0,1,0},
- {0,0,1,1},
- {0,1,0,0},
- {0,1,0,1},
- {0,1,1,0},
- {0,1,1,1},
- {1,0,0,0},
- {1,0,0,1},
- {1,0,1,0},
- {1,0,1,1},
- {1,1,0,0},
- {1,1,0,1},
- {1,1,1,0},
- {1,1,1,1}};
- /* display plane buffers (for fast scanline drawing) */
- static char plane0[256];
- static char plane1[256];
- static char plane2[256];
- static char plane3[256];
- static char text_regs[MAX_REGS]; /* VGA registers for saved text mode */
- /* saved text mode palette values */
- static char text_red[256];
- static char text_green[256];
- static char text_blue[256];
- /* saved graphics mode palette values */
- static char graph_red[256];
- static char graph_green[256];
- static char graph_blue[256];
- static int prv_mode = TEXT; /* previous video mode */
- static int cur_mode = TEXT; /* current video mode */
- static int flip_mode = TEXT; /* flipped video mode */
- static struct info cur_info; /* current video parameters */
- static int cur_color; /* current color */
- static int initialized = 0; /* flag: initialize() called ? */
- static int flip = 0; /* flag: executing vga_flip() ? */
- static int et4000 = 0; /* flag: ET4000 or standard VGA */
- static int tty0_fd; /* /dev/tty0 file descriptor */
- static int mem_fd; /* /dev/mem file descriptor */
- static FILE* console; /* console input stream */
- static char* graph_mem; /* dummy buffer for mmapping grahics memory */
- static char* graph_buf = NULL; /* saves graphics data during flip */
- static char font_buf1[FONT_SIZE]; /* saved font data - plane 2 */
- static char font_buf2[FONT_SIZE]; /* saved font data - plane 3 */
- static char null_buf[NULL_SIZE]; /* used to speed up clear */
- static struct termios text_termio; /* text mode termio parameters */
- static struct termios graph_termio; /* graphics mode termio parameters */
- int flipchar = '\x1b'; /* flip character - initially ESCAPE */
- static void inline port_out(char value, unsigned short port)
- {
- __asm__ volatile ("outb %0,%1"
- ::"a" ((char) value),"d" ((unsigned short) port));
- }
- static char inline port_in(unsigned short port)
- {
- char _v;
- __asm__ volatile ("inb %1,%0"
- :"=a" (_v):"d" ((unsigned short) port));
- return _v;
- }
- static void set_graphtermio()
- {
- /* set graphics mode termio parameters */
- ioctl(0, TCSETSW, &graph_termio);
- }
- static void set_texttermio()
- {
- /* restore text mode termio parameters */
- ioctl(0, TCSETSW, &text_termio);
- }
- static void disable_interrupt()
- {
- struct termios cur_termio;
- ioctl(0, TCGETS, &cur_termio);
- cur_termio.c_lflag &= ~ISIG;
- ioctl(0, TCSETSW, &cur_termio);
- }
- static void enable_interrupt()
- {
- struct termios cur_termio;
- ioctl(0, TCGETS, &cur_termio);
- cur_termio.c_lflag |= ISIG;
- ioctl(0, TCSETSW, &cur_termio);
- }
- static int get_perm()
- {
- /* get I/O permissions for VGA registers */
- if (ioperm(CRT_IC, 1, 1)) {
- printf("VGAlib: can't get I/O permissions \n");
- exit (-1);
- }
- ioperm(CRT_IM, 1, 1);
- ioperm(ATT_IW, 1, 1);
- ioperm(GRA_I, 1, 1);
- ioperm(SEQ_I, 1, 1);
- ioperm(PEL_IW, 1, 1);
- ioperm(PEL_IR, 1, 1);
- ioperm(CRT_DC, 1, 1);
- ioperm(CRT_DM, 1, 1);
- ioperm(ATT_R, 1, 1);
- ioperm(GRA_D, 1, 1);
- ioperm(SEQ_D, 1, 1);
- ioperm(MIS_R, 1, 1);
- ioperm(MIS_W, 1, 1);
- ioperm(IS1_RC, 1, 1);
- ioperm(IS1_RM, 1, 1);
- ioperm(PEL_D, 1, 1);
- /* ET4000 registers */
- ioperm(0x3bf, 1, 1);
- ioperm(0x3cc, 1, 1);
- ioperm(0x3d8, 1, 1);
- ioperm(0x3b8, 1, 1);
- ioperm(0x3c3, 1, 1);
- ioperm(0x3cd, 1, 1);
- /* color or monochrome text emulation? */
- color_text = port_in(MIS_R)&0x01;
- /* chose registers for color/monochrome emulation */
- if (color_text) {
- CRT_I = CRT_IC;
- CRT_D = CRT_DC;
- IS1_R = IS1_RC;
- } else {
- CRT_I = CRT_IM;
- CRT_D = CRT_DM;
- IS1_R = IS1_RM;
- }
- }
- static int et4000_test()
- {
- char new, old, val;
- int base;
- /* test for Tseng clues */
- old = port_in(0x3cd);
- port_out(0x55, 0x3cd);
- new = port_in(0x3cd);
- port_out(old, 0x3cd);
- /* return false if not Tseng */
- if (new != 0x55)
- return 0;
- /* test for ET4000 clues */
- if (port_in(0x3cc) & 1)
- base = 0x3d4;
- else
- base = 0x3b4;
- port_out(0x33, base);
- old = port_in(base+1);
- new = old ^ 0xf;
- port_out(new, base+1);
- val = port_in(base+1);
- port_out(old, base+1);
- /* return true if ET4000 */
- return (val == new);
- }
- static int et4000_save_regs(char regs[])
- {
- int i;
- /* save extended CRT registers */
- for (i = 0; i < 6; i++) {
- port_out(0x32+i, CRT_I);
- regs[EXT+i] = port_in(CRT_D);
- }
- /* save extended sequencer register */
- port_out(7, SEQ_I);
- regs[EXT+6] = port_in(SEQ_D);
- /* save some other ET4000 specific registers */
- regs[EXT+7] = port_in(0x3c3);
- regs[EXT+8] = port_in(0x3cd);
- /* save extended attribute register */
- port_in(IS1_R); /* reset flip flop */
- port_out(0x16, ATT_IW);
- regs[EXT+9] = port_in(ATT_R);
- }
- static int et4000_set_regs(char regs[])
- {
- int i;
- /* write some ET4000 specific registers */
- port_out(regs[EXT+7], 0x3c3);
- port_out(regs[EXT+8], 0x3cd);
- /* write extended sequencer register */
- port_out(7, SEQ_I);
- port_out(regs[EXT+6], SEQ_D);
- /* write extended CRT registers */
- for (i = 0; i < 6; i++) {
- port_out(0x32+i, CRT_I);
- port_out(regs[EXT+i], CRT_D);
- }
- /* write extended attribute register */
- port_in(IS1_R); /* reset flip flop */
- port_out(0x16, ATT_IW);
- port_out(regs[EXT+9], ATT_IW);
- }
- static int save_regs(char regs[])
- {
- int i;
- /* save VGA registers */
- for (i = 0; i < CRT_C; i++) {
- port_out(i, CRT_I);
- regs[CRT+i] = port_in(CRT_D);
- }
- for (i = 0; i < ATT_C; i++) {
- port_in(IS1_R);
- port_out(i, ATT_IW);
- regs[ATT+i] = port_in(ATT_R);
- }
- for (i = 0; i < GRA_C; i++) {
- port_out(i, GRA_I);
- regs[GRA+i] = port_in(GRA_D);
- }
- for (i = 0; i < SEQ_C; i++) {
- port_out(i, SEQ_I);
- regs[SEQ+i] = port_in(SEQ_D);
- }
- regs[MIS] = port_in(MIS_R);
- if (et4000)
- et4000_save_regs(regs);
- }
- static int set_regs(char regs[], int mode)
- {
- int i;
- /* disable video */
- port_in(IS1_R);
- port_out(0x00, ATT_IW);
-
- /* update misc output register */
- port_out(regs[MIS], MIS_W);
- /* synchronous reset on */
- port_out(0x00,SEQ_I);
- port_out(0x01,SEQ_D);
-
- /* write sequencer registers */
- for (i = 1; i < SEQ_C; i++) {
- port_out(i, SEQ_I);
- port_out(regs[SEQ+i], SEQ_D);
- }
- /* synchronous reset off */
- port_out(0x00, SEQ_I);
- port_out(0x03, SEQ_D);
-
- /* deprotect CRT registers 0-7 */
- port_out(0x11, CRT_I);
- port_out(port_in(CRT_D)&0x7F, CRT_D);
-
- /* write CRT registers */
- for (i = 0; i < CRT_C; i++) {
- port_out(i, CRT_I);
- port_out(regs[CRT+i], CRT_D);
- }
- /* write graphics controller registers */
- for (i = 0; i < GRA_C; i++) {
- port_out(i, GRA_I);
- port_out(regs[GRA+i], GRA_D);
- }
-
- /* write attribute controller registers */
- for (i = 0; i < ATT_C; i++) {
- port_in(IS1_R); /* reset flip-flop */
- port_out(i, ATT_IW);
- port_out(regs[ATT+i],ATT_IW);
- }
- if (et4000)
- if (mode == G640x480x256 || mode == G800x600x256 || mode == G1024x768x256)
- et4000_set_regs(regs);
- }
- static void interrupt_handler(int value)
- {
- /* handle SIGINT - restore text mode and exit */
- if (cur_mode != TEXT)
- vga_setmode(TEXT);
- set_texttermio();
- exit(-1);
- }
- static void initialize()
- {
- int i, j;
- /* save text mode termio parameters */
- ioctl(0, TCGETS, &text_termio);
- graph_termio = text_termio;
- /* change termio parameters to allow our own I/O processing */
- graph_termio.c_iflag &= ~(BRKINT|PARMRK|INPCK|IUCLC|IXON|IXOFF);
- graph_termio.c_iflag |= (IGNBRK|IGNPAR);
- graph_termio.c_oflag &= ~(ONOCR);
- graph_termio.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|NOFLSH);
- graph_termio.c_lflag |= (ISIG); /* enable interrupt */
- graph_termio.c_cc[VMIN] = 1;
- graph_termio.c_cc[VTIME] = 0;
- graph_termio.c_cc[VSUSP] = 0; /* disable suspend */
- disable_interrupt();
- get_perm();
- et4000 = et4000_test();
- if (et4000) {
- /* get acces to extended registers */
- port_out(3, 0x3bf);
- if (port_in( 0x3cc ) & 1)
- port_out(0xa0, 0x3d8);
- else
- port_out(0xa0, 0x3b8);
- }
-
- /* open /dev/tty0 - current virtual console */
- if ((tty0_fd = open("/dev/tty0", O_RDONLY) ) < 0) {
- printf("VGAlib: can't open /dev/tty0 \n");
- exit (-1);
- }
- console = fdopen(tty0_fd, "r");
- /* disable text output to console */
- ioctl(tty0_fd, KDSETMODE, KD_GRAPHICS);
-
- /* open /dev/mem */
- if ((mem_fd = open("/dev/mem", O_RDWR) ) < 0) {
- printf("VGAlib: can't open /dev/mem \n");
- exit (-1);
- }
- /* mmap graphics memory */
- if ((graph_mem = malloc(GRAPH_SIZE + (PAGE_SIZE-1))) == NULL) {
- printf("VGAlib: allocation error \n");
- exit (-1);
- }
- if ((unsigned long)graph_mem % PAGE_SIZE)
- graph_mem += PAGE_SIZE - ((unsigned long)graph_mem % PAGE_SIZE);
- graph_mem = (char *)mmap(
- (caddr_t)graph_mem,
- GRAPH_SIZE,
- PROT_READ|PROT_WRITE,
- MAP_SHARED|MAP_FIXED,
- mem_fd,
- GRAPH_BASE
- );
- if ((long)graph_mem < 0) {
- printf("VGAlib: mmap error \n");
- exit (-1);
- }
- /* disable video */
- port_in(IS1_R);
- port_out(0x00, ATT_IW);
-
- save_regs(text_regs);
- /* save text mode palette - first select palette index 0 */
- port_out(0, PEL_IR);
- /* read RGB components - index is autoincremented */
- for(i = 0; i < 256; i++) {
- for(j = 0; j < 10; j++) ; /* delay (minimum 240ns) */
- text_red[i] = port_in(PEL_D);
- for(j = 0; j < 10; j++) ; /* delay (minimum 240ns) */
- text_green[i] = port_in(PEL_D);
- for(j = 0; j < 10; j++) ; /* delay (minimum 240ns) */
- text_blue[i] = port_in(PEL_D);
- }
- /* shift to color emulation */
- CRT_I = CRT_IC;
- CRT_D = CRT_DC;
- IS1_R = IS1_RC;
- port_out(port_in(MIS_R)|0x01, MIS_W);
- /* save font data - first select a 16 color graphics mode */
- set_regs(g640x480x16_regs, G640x480x16);
- /* save font data in plane 2 */
- port_out(0x04, GRA_I);
- port_out(0x02, GRA_D);
- memcpy(font_buf1, graph_mem, FONT_SIZE);
- /* save font data in plane 3 */
- port_out(0x04, GRA_I);
- port_out(0x03, GRA_D);
- memcpy(font_buf2, graph_mem, FONT_SIZE);
- /* initialize buffer used when clearing in 256 color modes */
- for(i = 0; i < NULL_SIZE; i++)
- null_buf[i] = 0;
- initialized = 1;
- /* do our own interrupt handling */
- (void) signal(SIGINT, interrupt_handler);
- }
- int vga_dumpregs()
- {
- char regs[MAX_REGS];
- int i;
- get_perm();
- et4000 = et4000_test();
- save_regs(regs);
- if (et4000)
- printf("static char regs[70] = {\n ");
- else
- printf("static char regs[60] = {\n ");
- for (i = 0; i < 12; i++)
- printf("0x%02X,", regs[CRT+i]);
- printf("\n ");
- for (i = 12; i < CRT_C; i++)
- printf("0x%02X,", regs[CRT+i]);
- printf("\n ");
- for (i = 0; i < 12; i++)
- printf("0x%02X,", regs[ATT+i]);
- printf("\n ");
- for (i = 12; i < ATT_C; i++)
- printf("0x%02X,", regs[ATT+i]);
- printf("\n ");
- for (i = 0; i < GRA_C; i++)
- printf("0x%02X,", regs[GRA+i]);
- printf("\n ");
- for (i = 0; i < SEQ_C; i++)
- printf("0x%02X,", regs[SEQ+i]);
- printf("\n ");
- printf("0x%02X", regs[MIS]);
- if (et4000) {
- printf(",\n ");
- for (i = 0; i < 9; i++)
- printf("0x%02X,", regs[EXT+i]);
- printf("0x%02X", regs[EXT+9]);
- }
- printf("\n};\n");
- }
- int vga_setmode(int mode)
- {
- int i;
- if (!initialized)
- initialize();
- disable_interrupt();
- prv_mode = cur_mode;
- cur_mode = mode;
- /* disable video */
- port_in(IS1_R);
- port_out(0x00, ATT_IW);
- if (et4000 && prv_mode == G1024x768x256)
- set_regs(g640x480x256_regs, G640x480x256);
- if (mode == TEXT) {
- /* restore font data - first select a 16 color graphics mode */
- set_regs(g640x480x16_regs, G640x480x16);
- /* disable Set/Reset Register */
- port_out(0x01, GRA_I );
- port_out(0x00, GRA_D );
- /* restore font data in plane 2 - necessary for all VGA's */
- port_out(0x02, SEQ_I );
- port_out(0x04, SEQ_D );
- memcpy(graph_mem, font_buf1, FONT_SIZE);
- /* restore font data in plane 3 - necessary for Trident VGA's */
- port_out(0x02, SEQ_I );
- port_out(0x08, SEQ_D );
- memcpy(graph_mem, font_buf2, FONT_SIZE);
- /* change register adresses if monochrome text mode */
- if (!color_text) {
- CRT_I = CRT_IM;
- CRT_D = CRT_DM;
- IS1_R = IS1_RM;
- port_out(port_in(MIS_R)&0xFE, MIS_W);
- }
- /* restore saved palette */
- for(i = 0; i < 256; i++)
- vga_setpalette(
- i, text_red[i], text_green[i], text_blue[i]
- );
- /* restore text mode VGA registers */
- set_regs(text_regs, TEXT);
- /* enable text output - restores the screen contents */
- ioctl(tty0_fd, KDSETMODE, KD_TEXT);
- /* enable video */
- port_in(IS1_R);
- port_out(0x20, ATT_IW);
-
- /* restore text mode termio */
- set_texttermio();
- } else {
- /* disable text output */
- ioctl(tty0_fd, KDSETMODE, KD_GRAPHICS);
- /* shift to color emulation */
- CRT_I = CRT_IC;
- CRT_D = CRT_DC;
- IS1_R = IS1_RC;
- port_out(port_in(MIS_R)|0x01, MIS_W);
- switch (mode) {
- case G320x200x16:
- set_regs(g320x200x16_regs, G320x200x16);
- cur_info = g320x200x16_info;
- break;
- case G640x200x16:
- set_regs(g640x200x16_regs, G640x200x16);
- cur_info = g640x200x16_info;
- break;
- case G640x350x16:
- set_regs(g640x350x16_regs, G640x350x16);
- cur_info = g640x350x16_info;
- break;
- case G640x480x16:
- set_regs(g640x480x16_regs, G640x480x16);
- cur_info = g640x480x16_info;
- break;
- case G320x200x256:
- set_regs(g320x200x256_regs, G320x200x256);
- cur_info = g320x200x256_info;
- break;
- case G320x240x256:
- set_regs(g320x240x256_regs, G320x240x256);
- cur_info = g320x240x256_info;
- break;
- case G320x400x256:
- set_regs(g320x400x256_regs, G320x400x256);
- cur_info = g320x400x256_info;
- break;
- case G360x480x256:
- set_regs(g360x480x256_regs, G360x480x256);
- cur_info = g360x480x256_info;
- break;
- case G640x480x2:
- set_regs(g640x480x2_regs, G640x480x2);
- cur_info = g640x480x2_info;
- break;
- case G640x480x256:
- set_regs(g640x480x256_regs, G640x480x256);
- cur_info = g640x480x256_info;
- break;
- case G800x600x256:
- set_regs(g800x600x256_regs, G800x600x256);
- cur_info = g800x600x256_info;
- break;
- case G1024x768x256:
- set_regs(g1024x768x256_regs, G1024x768x256);
- cur_info = g1024x768x256_info;
- break;
- }
- if (!flip) {
- /* set default palette */
- for(i = 0; i < 256; i++)
- vga_setpalette(
- i, default_red[i], default_green[i], default_blue[i]
- );
-
- /* clear screen (sets current color to 15) */
- vga_clear();
- }
- /* enable video */
- port_in(IS1_R);
- port_out(0x20, ATT_IW);
-
- /* set graphics mode termio */
- set_graphtermio();
- }
- return 0;
- }
- int vga_hasmode(int mode)
- {
- switch (mode) {
- case TEXT:
- case G320x200x16:
- case G640x200x16:
- case G640x350x16:
- case G640x480x16:
- case G640x480x2:
- case G320x200x256:
- case G320x240x256:
- case G320x400x256:
- case G360x480x256:
- return 1;
- case G640x480x256:
- case G800x600x256:
- case G1024x768x256:
- get_perm();
- return et4000_test();
- default:
- return 0;
- }
- }
- int vga_clear()
- {
- int i, j;
- vga_screenoff();
- switch (cur_mode) {
- case G320x200x16:
- case G640x200x16:
- case G640x350x16:
- case G640x480x16:
- case G640x480x2:
- vga_setcolor(0);
- /* write to all bits */
- port_out(0x08, GRA_I );
- port_out(0xFF, GRA_D );
- /* write dummy values to clear video memory */
- for(i = 0; i < 16; i++)
- memcpy(graph_mem + i*NULL_SIZE, null_buf, NULL_SIZE);
- break;
- case G320x200x256:
- case G320x240x256:
- case G320x400x256:
- case G360x480x256:
- /* write to all planes */
- port_out(0x02, SEQ_I );
- port_out(0x0F, SEQ_D );
-
- /* clear video memory */
- for(i = 0; i < 16; i++)
- memcpy(graph_mem + i*NULL_SIZE, null_buf, NULL_SIZE);
- break;
- case G640x480x256:
- case G800x600x256:
- case G1024x768x256:
- for(i = 0; i < 16; i++) {
- /* select segment */
- port_out(i, SEG_SELECT);
- /* clear video memory */
- for(j = 0; j < 16; j++)
- memcpy(graph_mem + j*NULL_SIZE, null_buf, NULL_SIZE);
- }
- break;
- }
- vga_setcolor(15);
-
- vga_screenon();
- return 0;
- }
- int vga_setpalette(int index, int red, int green, int blue)
- {
- int i;
- /* select palette register */
- port_out(index, PEL_IW);
- /* write RGB components */
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- port_out(red, PEL_D);
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- port_out(green, PEL_D);
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- port_out(blue, PEL_D);
- return 0;
- }
- int vga_getpalette(int index, int *red, int *green, int *blue)
- {
- int i;
- /* select palette register */
- port_out(index, PEL_IR);
- /* read RGB components */
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- *red = (int) port_in(PEL_D);
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- *green = (int) port_in(PEL_D);
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- *blue = (int) port_in(PEL_D);
- return 0;
- }
- int vga_setpalvec(int start, int num, int *pal)
- {
- int i, j;
- /* select palette register */
- port_out(start, PEL_IW);
- for(j = 0; j < num; j++) {
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- port_out(*(pal++), PEL_D);
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- port_out(*(pal++), PEL_D);
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- port_out(*(pal++), PEL_D);
- }
- return j;
- }
- int vga_getpalvec(int start, int num, int *pal)
- {
- int i, j;
- /* select palette register */
- port_out(start, PEL_IR);
- for(j = 0; j < num; j++) {
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- *(pal++) = (int) port_in(PEL_D);
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- *(pal++) = (int) port_in(PEL_D);
- for(i = 0; i < 10; i++) ; /* delay (minimum 240ns) */
- *(pal++) = (int) port_in(PEL_D);
- }
- return i;
- }
- int vga_setcolor(int color)
- {
- switch (cur_mode) {
- case G320x200x16:
- case G640x200x16:
- case G640x350x16:
- case G640x480x16:
- /* update set/reset register */
- port_out(0x00, GRA_I );
- port_out(color, GRA_D );
- break;
- case G640x480x2:
- if (color != 0)
- color = 15;
- /* update set/reset register */
- port_out(0x00, GRA_I );
- port_out(color, GRA_D );
- break;
- case G320x200x256:
- case G320x240x256:
- case G320x400x256:
- case G360x480x256:
- case G640x480x256:
- case G800x600x256:
- case G1024x768x256:
- cur_color = color;
- break;
- }
-
- return 0;
- }
- int vga_drawpixel(int x, int y)
- {
- unsigned long offset;
- switch (cur_mode) {
- case G320x200x16:
- case G640x200x16:
- case G640x350x16:
- case G640x480x16:
- case G640x480x2:
- /* select bit */
- port_out(8, GRA_I);
- port_out(0x80 >> (x & 7), GRA_D);
- /* read into latch and write dummy back */
- offset = y*cur_info.xbytes + (x>>3);
- graph_mem[offset] = graph_mem[offset];
- break;
- case G320x200x256:
- /* write color to pixel */
- graph_mem[y*320 + x] = cur_color;
- break;
- case G320x240x256:
- case G320x400x256:
- case G360x480x256:
- /* select plane */
- port_out(0x02, SEQ_I);
- port_out(1 << (x & 3), SEQ_D);
- /* write color to pixel */
- graph_mem[y*cur_info.xbytes + (x>>2)] = cur_color;
- break;
- case G640x480x256:
- case G800x600x256:
- case G1024x768x256:
- offset = (y<<10)+x;
- /* select segment */
- port_out(offset >> 16, SEG_SELECT);
- /* write color to pixel */
- graph_mem[offset & 0xFFFF] = cur_color;
- break;
- }
-
- return 0;
- }
- int vga_drawscanline(int line, char* colors)
- {
- if (cur_mode == G640x480x2)
- vga_drawscansegment(colors, 0, line, cur_info.xbytes);
- else
- vga_drawscansegment(colors, 0, line, cur_info.xdim);
- }
- int vga_drawscansegment(char* colors, int x, int y, int length)
- {
- /* both length and x must divide with 8 */
- switch (cur_mode) {
- case G320x200x16:
- case G640x200x16:
- case G640x350x16:
- case G640x480x16:
- {
- int i, j, k, first, last;
- union bits bytes;
- char* address;
- k = 0;
- for(i = 0; i < length; i += 8) {
- bytes.i = 0;
- first = i;
- last = i+8;
- for(j = first; j < last; j++)
- bytes.i = (bytes.i<<1) | color16[colors[j]].i;
- plane0[k] = bytes.b.bit0;
- plane1[k] = bytes.b.bit1;
- plane2[k] = bytes.b.bit2;
- plane3[k++] = bytes.b.bit3;
- }
- address = graph_mem + (y*cur_info.xdim+x)/8;
- /* disable Set/Reset Register */
- port_out(0x01, GRA_I );
- port_out(0x00, GRA_D );
- /* write to all bits */
- port_out(0x08, GRA_I );
- port_out(0xFF, GRA_D );
- /* select map mask register */
- port_out(0x02, SEQ_I );
- /* write plane 0 */
- port_out(0x01, SEQ_D );
- memcpy(address, plane0, length/8);
- /* write plane 1 */
- port_out(0x02, SEQ_D );
- memcpy(address, plane1, length/8);
- /* write plane 2 */
- port_out(0x04, SEQ_D );
- memcpy(address, plane2, length/8);
- /* write plane 3 */
- port_out(0x08, SEQ_D );
- memcpy(address, plane3, length/8);
- /* restore map mask register */
- port_out(0x0F, SEQ_D );
-
- /* enable Set/Reset Register */
- port_out(0x01, GRA_I );
- port_out(0x0F, GRA_D );
- }
- break;
- case G640x480x2:
- {
- /* disable Set/Reset Register */
- port_out(0x01, GRA_I );
- port_out(0x00, GRA_D );
- /* write to all bits */
- port_out(0x08, GRA_I );
- port_out(0xFF, GRA_D );
- /* write to all planes */
- port_out(0x02, SEQ_I );
- port_out(0x0F, SEQ_D );
- memcpy(graph_mem + (y*cur_info.xdim+x)/8, colors, length);
- /* restore map mask register */
- port_out(0x0F, SEQ_D );
-
- /* enable Set/Reset Register */
- port_out(0x01, GRA_I );
- port_out(0x0F, GRA_D );
- }
- break;
- case G320x200x256:
- /* linear addressing - easy and fast */
- memcpy(graph_mem + y*cur_info.xdim+x, colors, length);
- break;
- case G320x240x256:
- case G320x400x256:
- case G360x480x256:
- {
- int first, last, offset, pixel, plane;
- /* select map mask register */
- port_out(0x02, SEQ_I);
- for(plane = 0; plane < 4; plane++) {
- /* select plane */
- port_out(1 << plane, SEQ_D);
- pixel = plane;
- first = (y*cur_info.xdim+x)/4;
- last = (y*cur_info.xdim+x+length)/4;
- for(offset = first; offset < last; offset++) {
- graph_mem[offset] = colors[pixel];
- pixel += 4;
- }
- }
- }
- break;
- case G640x480x256:
- case G800x600x256:
- case G1024x768x256:
- {
- unsigned long offset;
- offset = (y<<10)+x;
- /* select segment */
- port_out(offset >> 16, SEG_SELECT);
- memcpy(graph_mem + (offset & 0xFFFF), colors, length);
- }
- break;
- }
-
- return 0;
- }
- int vga_drawline(int x1, int y1, int x2, int y2)
- {
- int dx = x2 - x1;
- int dy = y2 - y1;
- int ax = ABS(dx) << 1;
- int ay = ABS(dy) << 1;
- int sx = (dx >= 0) ? 1 : -1;
- int sy = (dy >= 0) ? 1 : -1;
-
- int x = x1;
- int y = y1;
- if (ax > ay) {
- int d = ay - (ax >> 1);
- while (x != x2) {
- vga_drawpixel(x, y);
- if (d > 0 || d == 0 && sx == 1) {
- y += sy;
- d -= ax;
- }
- x += sx;
- d += ay;
- }
- } else {
- int d = ax - (ay >> 1);
- while (y != y2) {
- vga_drawpixel(x, y);
- if (d > 0 || d == 0 && sy == 1) {
- x += sx;
- d -= ay;
- }
- y += sy;
- d += ax;
- }
- }
- vga_drawpixel(x, y);
-
- return 0;
- }
- int vga_screenoff()
- {
- /* turn off screen for faster VGA memory acces */
- port_out(0x01, SEQ_I);
- port_out(port_in(SEQ_D)|0x20, SEQ_D);
- return 0;
- }
- int vga_screenon()
- {
- /* turn screen back on */
- port_out(0x01, SEQ_I);
- port_out(port_in(SEQ_D)&0xDF, SEQ_D);
- return 0;
- }
- int vga_getxdim()
- {
- return cur_info.xdim;
- }
- int vga_getydim()
- {
- return cur_info.ydim;
- }
- int vga_getcolors()
- {
- return cur_info.colors;
- }
- int vga_getch()
- {
- char c;
- if (cur_mode == TEXT)
- return -1;
- read(tty0_fd, &c, 1);
- while(c == flipchar) {
- vga_flip();
- set_graphtermio();
- read(tty0_fd, &c, 1);
- vga_flip();
- read(tty0_fd, &c, 1);
- }
- return c;
- }
- int vga_setflipchar(int c)
- {
- flipchar = c;
- return 0;
- }
- int vga_flip()
- {
- int i, j;
- if (cur_mode == TEXT && flip_mode == TEXT)
- return -1;
- flip = 1;
- disable_interrupt();
- /* disable video */
- port_in(IS1_R);
- port_out(0x00, ATT_IW);
-
- if (cur_mode == TEXT) {
- /* disable text output */
- ioctl(tty0_fd, KDSETMODE, KD_GRAPHICS);
- /* restore all four planes - first select a 16 color graphics mode */
- set_regs(g640x480x16_regs, G640x480x16);
- /* disable Set/Reset Register */
- port_out(0x01, GRA_I );
- port_out(0x00, GRA_D );
- for(i = 0; i < 4; i++) {
- /* restore plane i */
- port_out(0x02, SEQ_I );
- port_out(1<<i, SEQ_D );
- memcpy(graph_mem, graph_buf + i*GRAPH_SIZE, GRAPH_SIZE);
- }
- free(graph_buf);
- /* restore saved palette */
- for(i = 0; i < 256; i++)
- vga_setpalette(
- i, graph_red[i], graph_green[i], graph_blue[i]
- );
- vga_setmode(flip_mode);
- flip_mode = TEXT;
- } else {
- /* save all four planes - first select a 16 color graphics mode */
- set_regs(g640x480x16_regs, G640x480x16);
- /* allocate memory for saved graphics data - only if necessary */
- if ((graph_buf = malloc(4*GRAPH_SIZE)) == NULL) {
- printf("vga_flip: allocation error \n");
- exit (-1);
- }
- for(i = 0; i < 4; i++) {
- /* save plane i */
- port_out(0x04, GRA_I);
- port_out( i, GRA_D);
- memcpy(graph_buf + i*GRAPH_SIZE, graph_mem, GRAPH_SIZE);
- }
- /* save graphics mode palette - first select palette index 0 */
- port_out(0, PEL_IR);
- /* read RGB components - index is autoincremented */
- for(i = 0; i < 256; i++) {
- for(j = 0; j < 10; j++) ; /* delay (minimum 240ns) */
- graph_red[i] = port_in(PEL_D);
- for(j = 0; j < 10; j++) ; /* delay (minimum 240ns) */
- graph_green[i] = port_in(PEL_D);
- for(j = 0; j < 10; j++) ; /* delay (minimum 240ns) */
- graph_blue[i] = port_in(PEL_D);
- }
- flip_mode = cur_mode;
- vga_setmode(TEXT);
- }
- flip = 0;
- return 0;
- }
|